#include "osd.h"
#include "boxx.h"
+#include "surfacevector.h"
char Boxx::numBoxxes = 0;
Boxx::Boxx()
rectangle(0, 0, area.w, area.h, colour);
}
-void Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour)
+int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsigned int skiplines)
{
char line[256];
int lineHeight = getFontHeight() + paraVSpace;
int linePos;
int ypos;
int printLine;
+ int leftlines=0;
+
+ int drawLinePos=-skiplines;
textPos = 0;
ypos = y;
if (printLine || (linePos > 1)) // if some text was put in line
{
- drawText(line, x, ypos, colour);
- ypos += lineHeight;
- if (ypos > (int)(area.h - lineHeight)) break;
+ if (ypos <= (int)(area.h - lineHeight + paraVSpace)) {
+ if (drawLinePos >= 0) {
+ drawText(line, x, ypos, colour);
+ ypos += lineHeight;
+ }
+ } else {
+ leftlines++;
+ }
+ drawLinePos++;
}
else
{
break;
}
}
+ return leftlines;
}
void Boxx::rectangle(Region& region, const DrawStyle& colour)
else if (surface) surface->drawMonoBitmap(base, dx,dy, height, width, nextColour);
}
+void Boxx::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner)
+{
+ if (parent) parent->drawTVMedia(tvmedia,area.x + x,area.y + y,width, height, corner);
+ else if (surface) {
+ SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
+ if (surfacevector) surfacevector->drawTVMedia(tvmedia,x, y,width, height, corner);
+ else surface->fillblt(x, y, width, height, DrawStyle::RED); // Signal that something went wrong
+ }
+
+}
+
+void Boxx::drawClippingRectangle(float x, float y, float w, float h)
+{
+ if (parent) parent->drawClippingRectangle(area.x + x, area.y + y, w, h);
+ else if (surface) {
+ SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
+ if (surfacevector) surfacevector->drawClippingRectangle(x, y, w, h);
+
+ }
+}
+
int Boxx::getFontHeight()
{
if (parent) return parent->getFontHeight();
#include "surface.h"
+#include "tvmedia.h"
+#include "osdvector.h"
class Bitmap;
// Drawing functions level 1
void fillColour(const DrawStyle & colour);
- void drawPara(const char* text, int x, int y, const DrawStyle& colour);
+ int drawPara(const char* text, int x, int y, const DrawStyle& colour, unsigned int skiplines=0);
// Drawing functions level 0
void rectangle(UINT x, UINT y, UINT w, UINT h, const DrawStyle& colour);
void drawBitmap(UINT x, UINT y, const Bitmap& bm, const DisplayRegion & region);
//Now deprecated
// void drawPixelAlpha(UINT x, UINT y, const Colour& colour,bool fastdraw=false);
+ void drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner=TopLeft);
+ void drawClippingRectangle(float x, float y, float w, float h);
int getFontHeight();
void drawJpeg(const char *fileName,int x, int y,int *width, int *height);
break;
}
+ case Message::PICTURES_ARRIVED:
+ {
+ Log::getInstance()->log("Command", Log::DEBUG, "TVMedia Pictures arrived");
+ OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
+ if (osdv) {
+ osdv->processReceivedPictures();
+ /* if (osdv->processReceivedPictures()) {
+ Log::getInstance()->log("Command", Log::DEBUG, "TVMedia Boxstack update triggered");
+ boxstack->update(NULL,NULL);
+ }*/
+ }
+ } break;
}
}
else
void Command::doFromTheTop(bool which)
{
+ if (isStandby) return;
if (which)
{
if (connLost)
}
edr->callinprogress = true;
- edUnlock();
- bool edrType = edr->call(userTag);
+ edUnlock();
+ bool edr_delete=false;
+ bool edrType = edr->call(userTag,edr_delete);
edLock();
edr->callinprogress = false;
#else
SetEvent(edr->cond);
#endif
+ if (edr_delete) delete edr;
}
edUnlock();
virtual ~EDReceiver();
protected:
- virtual bool call(void* userTag)=0; // Implementor must override this and do the actual call
+ virtual bool call(void* userTag, bool & deleteme)=0; // Implementor must override this and do the actual call
// return true to have EventDispatcher remove receiver from list after call
bool nomorecalls;
bool callinprogress;
const static ULONG TELETEXTUPDATEFIRSTLINE = 33;
const static ULONG SUBTITLE_CHANGE_CHANNEL = 34;
const static ULONG MOUSE_ANDROID_SCROLL = 35;
+ const static ULONG PICTURES_ARRIVED = 36;
};
#endif
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "movieinfo.h"
+
+MovieInfo::MovieInfo()
+{
+ id=0;
+ title="";
+ originalTitle="";
+ tagline="";
+ overview="";
+ adult=0;
+ collectionName="";
+
+ budget=0;
+ revenue=0;
+ genres="";
+ homepage="";
+ releaseDate="";
+ runtime=0;
+ popularity=0.f;
+ voteAverage=0.f;
+
+
+
+}
+
+
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef MOVIEINFO_H
+#define MOVIEINFO_H
+
+#include "tvmedia.h"
+
+class MovieInfo {
+public:
+ MovieInfo();
+
+ int id;
+
+ std::string title;
+ std::string originalTitle;
+ std::string tagline;
+ std::string overview;
+ UCHAR adult;
+ std::string collectionName;
+
+ int budget;
+ int revenue;
+ std::string genres;
+ std::string homepage;
+ std::string releaseDate;
+ int runtime;
+ float popularity;
+ float voteAverage;
+
+ TVMedia poster;
+ TVMedia fanart;
+ TVMedia collectionPoster;
+ TVMedia collectionFanart;
+ Actors actors;
+};
+
+
+#endif
imagereader.o mediaoptions.o mediaplayer.o \
serialize.o localmediafile.o playermedia.o \
demuxermedia.o tfeed.o vteletextview.o teletextdecodervbiebu.o \
- teletxt/txtfont.o mediafile.o
+ teletxt/txtfont.o mediafile.o movieinfo.o seriesinfo.o wmovieview.o wseriesview.o tvmedia.o \
+ wpictureview.o
+
virtual int getFontNames(const char *** names,const char *** names_keys){ return 0;};
virtual void setFont(const char * fontname){};
+ virtual float getPixelAspect() {return 1.f;};
+
protected:
static Osd* instance;
int initted;
return 1;
}
+void OsdOpenVG::getScreenSize(int &width, int &height)
+{
+ width=BACKBUFFER_WIDTH;
+ height=BACKBUFFER_HEIGHT;
+}
+
void OsdOpenVG::initPaths()
{
vgLoadIdentity();
vgScale(((float)BACKBUFFER_WIDTH)/720.f, -((float)BACKBUFFER_HEIGHT)/576.f);
vgTranslate(0.f+sc.x,-576.f+sc.y);
+ clip_shift_x=sc.x;
+ clip_shift_y=sc.y;
case DrawImage: {
vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
vgGetMatrix(save_matrix);
- vgTranslate(command.x,command.y);
-
-
+ VGfloat imagewidth=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_WIDTH);
+ VGfloat imageheight=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_HEIGHT);
//vgScale(command.w,command.h);
- VGfloat imagewidth=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_WIDTH);
- VGfloat imageheight=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_HEIGHT);
+
if (command.reference) { //special behaviout for bw images they act as a mask on the current paint
+ vgTranslate(command.x,command.y);
vgSetPaint((VGPaint) command.reference,VG_FILL_PATH);
vgSetPaint((VGPaint) command.reference,VG_STROKE_PATH);
vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_STENCIL);
//vgScale(720.f/((float)BACKBUFFER_WIDTH), 576.f/((float)BACKBUFFER_HEIGHT));
float scalex=command.w/imagewidth;
float scaley=command.h/imageheight;
+ if (scalex==0.f && scaley==0.f) {
+ scalex=aspect_correction;
+ scaley=1.f;
+ } else if (scalex==0.f) {
+ scalex=scaley*aspect_correction;
+ } else if (scaley==0.f) {
+ scaley=scalex/aspect_correction;
+ }
+ float tx=command.x;
+ float ty=command.y;
+
+ if (command.corner == BottomRight || command.corner == BottomLeft || command.corner == BottomMiddle)
+ {
+ ty-=imageheight * scaley;
+ }
+
+ if (command.corner == BottomRight || command.corner == TopRight)
+ {
+ tx-=imagewidth * scalex;
+ }
+
+ if (command.corner == BottomMiddle || command.corner == TopMiddle)
+ {
+ tx-=imagewidth * scalex *0.5f;
+ }
+
+ vgTranslate(tx,ty);
//vgScale(command.w/imagewidth,command.h/imageheight);
vgScale(scalex,scaley);
vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL);
vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
}break;
+ case DrawClipping: {
+ VGint coords[4]={0,0,0,0};
+ coords[0]= ((command.x+clip_shift_x)*((float)BACKBUFFER_WIDTH)/720.f);
+ coords[1]= ((576.f-command.y-clip_shift_y-command.h)*((float)BACKBUFFER_HEIGHT)/576.f);
+ coords[2]= ((command.w-1.f)*((float)BACKBUFFER_WIDTH)/720.f);
+ coords[3]= ((command.h-1.f)*((float)BACKBUFFER_HEIGHT)/576.f);
+ vgSetiv(VG_SCISSOR_RECTS, 4,coords);
+ if (command.w==0.f && command.h==0.f)
+ vgSeti(VG_SCISSORING,VG_FALSE);
+ else vgSeti(VG_SCISSORING,VG_TRUE);
+ } break;
}
}
} break;
case OVGcreateMonoBitmap: {
VGImage handle=vgCreateImage(VG_A_1,command.param1, command.param2,
- VG_IMAGE_QUALITY_NONANTIALIASED|
- VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);
+ VG_IMAGE_QUALITY_FASTER);
//Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono %d %d %x %d",command.param1,command.param2,vgGetError(),handle);
unsigned int buffer_len=(command.param1*command.param2)>>3;
unsigned char * buffer=(unsigned char*)malloc(buffer_len);
handle=vgCreateImage(VG_sXBGR_8888,imagefile->columns(),imagefile->rows(),
- VG_IMAGE_QUALITY_NONANTIALIASED|
- VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);
- // Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark1",imagefile->columns(),imagefile->rows(),*(unsigned int*)imageblob.data());
+ VG_IMAGE_QUALITY_BETTER);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark1",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data());
vgImageSubData(handle,imageblob.data(),imagefile->columns()*4,
VG_sXBGR_8888,0,0,imagefile->columns(),imagefile->rows());
- // Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark2",imagefile->columns(),imagefile->rows(),*(unsigned int*)imageblob.data());
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark2",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data());
delete imagefile;
}catch( Exception &error_ )
{
return putOpenVGCommand(comm,true);
}
+ImageIndex OsdOpenVG::createPicture(unsigned char *data, unsigned int length)
+{
+ Image* magicimage=NULL;
+ bool mem=false;
+ struct OpenVGCommand comm;
+ comm.task=OVGcreateImageFile;
+
+ try{
+ // Now figure out, if it is a special case
+ //Log::getInstance()->log("OSD", Log::DEBUG, "createPicture");
+ magicimage=new Image(Blob(data,length)); // fix me this is an unnecessary memcpy
+ free(data);
+ }catch( Exception &error_ )
+ {
+ Log::getInstance()->log("OSD", Log::DEBUG, "Libmagick: %s",error_.what());
+
+ return 0;
+ }
+ comm.data=magicimage;
+ return putOpenVGCommand(comm,true);
+}
+
+
+
ImageIndex OsdOpenVG::createMonoBitmap(void *base,int width,int height)
{
struct OpenVGCommand comm;
virtual void setFont(const char * fontname);
+ virtual float getPixelAspect() {return aspect_correction;};
+
protected:
/*osd vector implementation*/
ImageIndex createJpeg(const char* fileName, int *width,int *height);
ImageIndex createMonoBitmap(void *base,int width,int height);
ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data);
+ ImageIndex createPicture(unsigned char *data, unsigned int length);
void destroyStyleRef(unsigned int index);
unsigned int createStyleRef(const DrawStyle &c);
unsigned int createColorRef(const Colour &c);
VGPath std_paths[Point+1];
long long lastrendertime;
void InternalRendering();
+ void getScreenSize(int &width, int &height);
vector<char*> fontnames_keys;
char * cur_fontname;
+ int clip_shift_x;
+ int clip_shift_y;
+
unsigned int loadTTchar(cTeletextChar c);
map<unsigned int,int> tt_font_chars;
#include "osdvector.h"
#include "surfacevector.h"
+#include "vdr.h"
+#include "vdrresponsepacket.h"
+#include "command.h"
+#include "message.h"
OsdVector::OsdVector()
{
setlocale(LC_CTYPE,"C.UTF-8");
+ picture_update=true;
}
OsdVector::~OsdVector()
}
itty1++;
}
+ int swidth,sheight;
+ getScreenSize(swidth,sheight);
//Now go through all surfaces and draw them
list<SurfaceCommands*>::iterator curdraw=todraw.begin();
while (curdraw!=todraw.end()) {
list<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
list<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
while (commands!=end) {
- executeDrawCommand(*commands);
+ // update any images loaded in the mean time
+ if ((*commands).instr==DrawImageLoading) {
+ LoadIndex loadindex=(*commands).target.loadindex;
+ if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
+ (*commands).instr=DrawImage;
+ (*commands).target.image=tvmedias_loaded[loadindex];;
+ incImageRef((*commands).target.image);
+ removeLoadIndexRef(loadindex);
+ }
+
+ }
+ // Now check if the command is on screen!
+ if (!(*commands).Outside(0,0,swidth,sheight)) {
+ executeDrawCommand(*commands);
+ }
commands++;
}
curdraw++;
surfaces_mutex.Unlock();
}
-
void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
list<SVGCommand>& commands)
{
new_sc.h=height;
itty=scommands.insert(itty,new_sc);
}
+ // update any images loaded in the mean time
+ list<SVGCommand>::iterator ilitty=commands.begin();
+
+ while (ilitty!=commands.end())
+ {
+ if ((*ilitty).instr==DrawImageLoading) {
+ LoadIndex loadindex=(*ilitty).target.loadindex;
+ if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
+
+ (*ilitty).instr=DrawImage;
+ (*ilitty).target.image=tvmedias_loaded[loadindex];
+ incImageRef((*ilitty).target.image);
+ removeLoadIndexRef(loadindex);
+ }
+ }
+ ilitty++;
+ }
+
+
// then clear and copy
(*itty).commands.clear();
(*itty).commands=commands;
incStyleRef((*sitty).getRef());
ImageIndex ii=(*sitty).getImageIndex();
if (ii) incImageRef(ii);
+ LoadIndex li=(*sitty).getLoadIndex();
+ if (li) incLoadIndexRef(li);
sitty++;
}
cleanupOrphanedRefs();
removeStyleRef((*sitty).getRef());
ImageIndex ii = (*sitty).getImageIndex();
if (ii) removeImageRef(ii);
+ LoadIndex li=(*sitty).getLoadIndex();
+ if (li) removeLoadIndexRef(li);
sitty++;
}
}
incStyleRef((*sitty).getRef());
ImageIndex ii=(*sitty).getImageIndex();
if (ii) incImageRef(ii);
+ LoadIndex li=(*sitty).getLoadIndex();
+ if (li) incLoadIndexRef(li);
sitty++;
}
}
+
void OsdVector::incImageRef(ImageIndex index)
{
if (images_ref.find(index)==images_ref.end()) {
images_ref[ref]--;
}
+unsigned int OsdVector::getLoadIndexRef(LoadIndex index)
+{
+ if (loadindex_ref.find(index)==loadindex_ref.end()) {
+ return -1;
+ } else {
+ return loadindex_ref[index];
+ }
+}
+
+void OsdVector::incLoadIndexRef(LoadIndex index)
+{
+ if (loadindex_ref.find(index)==loadindex_ref.end()) {
+ loadindex_ref[index]=1;
+ } else {
+ loadindex_ref[index]++;
+ }
+}
+
+void OsdVector::removeLoadIndexRef(const LoadIndex ref)
+{
+ loadindex_ref[ref]--;
+ if (loadindex_ref[ref]==0) {
+ //now check, if it is already loaded
+ map<LoadIndex,ImageIndex>::iterator itty=tvmedias_loaded.find(ref);
+ if ( itty != tvmedias_loaded.end()) {
+ removeImageRef((*itty).second); // remove lock
+ }
+ tvmedias_loaded.erase(ref);
+ tvmedias_load.erase(tvmedias_load_inv[ref]);
+ tvmedias_load_inv.erase(ref);
+ }
+}
+
void OsdVector::cleanupOrphanedRefs()
{ // Do some garbage collection
} else ++jitty;
}
+ map<TVMediaInfo,ImageIndex>::iterator titty=tvmedias.begin();
+ while (titty!=tvmedias.end()) {
+ map<ImageIndex,unsigned int>::iterator curitty=images_ref.find((*titty).second);
+ int count=(*curitty).second;
+ if (count==0) {
+
+ Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia destroy Picture");
+ ImageIndex ref=(*curitty).first;
+ tvmedias.erase(titty++);
+ images_ref.erase(curitty++);
+ destroyImageRef(ref);
+ } else ++titty;
+ }
+
map<pair<Colour*,unsigned int>,unsigned int>::iterator sitty=styles.begin();
while (sitty!=styles.end()) {
}
}
+LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image)
+{
+ ImageIndex image_handle=0;
+ LoadIndex loadindex=0;
+ if (tvmedias.find(tvmedia)==tvmedias.end())
+ {
+ loadindex=loadTVMedia(tvmedia);
+ } else {
+ image_handle=tvmedias[tvmedia];
+ if (images_ref.find(image_handle)==images_ref.end()) {
+ //invalid handle recreate
+ loadindex=loadTVMedia(tvmedia);
+ image_handle=0;
+ } else {
+ incImageRef(image_handle);
+ }
+ }
+ /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
+ incImageRef(image_handle);*/
+ image=image_handle;
+ return loadindex;
+}
+
+LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
+{
+ LoadIndex index=0;
+ if (tvmedias_load.find(tvmedia)==tvmedias_load.end())
+ {
+ index=VDR::getInstance()->loadTVMedia(tvmedia);
+ tvmedias_load[tvmedia]=index;
+ tvmedias_load_inv[index]=tvmedia;
+ } else {
+ index=tvmedias_load[tvmedia];
+ }
+
+ incLoadIndexRef(index);
+
+ return index;
+}
+
+void OsdVector::setTVMedia(LoadIndex index, unsigned char * buffer, unsigned int length)
+{
+ //Beware for thread safety
+ ImageIndex image_index=0;
+
+ TVMediaInfo tvmedia=tvmedias_load_inv[index];
+ Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %d arrived",index);
+ if (buffer) {
+ if (getLoadIndexRef(index)<1) {
+ // we do not want the picture anymore . Really...
+ } else {
+ image_index=tvmedias[tvmedia]=createPicture(buffer,length);
+ tvmedias_loaded[index]=image_index;
+ incImageRef(image_index); // hold one index until all loadings refs are gone;
+ }
+ }
+
+
+}
+
+
+
ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
{
ImageIndex image_handle=0;
incImageRef(image_handle);
return image_handle;
}
+
+void OsdVector::receivePicture(VDR_ResponsePacket *vresp)
+{
+ pict_lock_incoming.Lock();
+ pict_incoming.push(vresp);
+ pict_lock_incoming.Unlock();
+ //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived");
+ if (picture_update) {
+ Message* m = new Message();
+ // This is incoming from VDR, we do not want to block gui so send a message to ourself to switch to gui thread
+ m->message=Message::PICTURES_ARRIVED;
+ m->from=this;
+ m->to=Command::getInstance();
+ picture_update=false;
+ Command::getInstance()->postMessageFromOuterSpace(m); // inform command about new picture
+ }
+}
+
+bool OsdVector::processReceivedPictures()
+{
+ bool ret=false;
+ pict_lock_incoming.Lock();
+ int i=0;
+ long long time1 = getTimeMS();
+ long long cur_time =time1;
+ while (pict_incoming.size() && (time1-cur_time)<100) {
+ VDR_ResponsePacket *vresp=pict_incoming.front();
+ pict_incoming.pop();
+ pict_lock_incoming.Unlock();
+ if (vresp->getFlag() != 2) {
+ setTVMedia(vresp->getStreamID(), vresp->getUserData(), vresp->getUserDataLength());
+ ret=true;
+ }
+ else setTVMedia(vresp->getStreamID(), NULL, 0);
+ delete vresp;
+ cur_time = getTimeMS();
+ pict_lock_incoming.Lock();
+ }
+ if (pict_incoming.size()==0) picture_update=true;
+ pict_lock_incoming.Unlock();
+
+
+ if (!picture_update) {
+ Message* m = new Message();
+ // We have remaing pictures! send a message to ourself to switch to gui thread
+ m->message=Message::PICTURES_ARRIVED;
+ m->from=this;
+ m->to=Command::getInstance();
+ picture_update=false;
+ Command::getInstance()->postMessageNoLock(m); // inform command about new picture
+ }
+ return ret;
+}
#include "colour.h"
#include <list>
#include <map>
+#include <queue>
#include <string>
+#include "tvmedia.h"
+#include "vdr.h"
#include "teletextdecodervbiebu.h"
enum SVGCommandInstr {
+ DrawNoop,
DrawPath,
DrawGlyph,
DrawImage,
- DrawTTchar
+ DrawTTchar,
+ DrawClipping,
+ DrawImageLoading
};
enum PathIndex {
HorzLine,
Point
};
+enum Corner{
+ TopLeft,
+ TopRight,
+ BottomLeft,
+ BottomRight,
+ TopMiddle,
+ BottomMiddle
+};
+
typedef unsigned int ImageIndex;
+typedef unsigned int LoadIndex;
class SVGCommand
{
public:
- SVGCommand(float ix, float iy,float iw,float ih,PathIndex path,unsigned int ref)
+ SVGCommand()
+ {
+ instr=DrawNoop;
+ x=y=w=h=reference=0;
+ };
+
+ static SVGCommand PaintPath(float ix, float iy,float iw,float ih,PathIndex path,unsigned int ref)
+ {
+ SVGCommand nc;
+ nc.instr=DrawPath;
+ nc.x=ix;
+ nc.y=iy;
+ nc.w=iw;
+ nc.h=ih;
+ nc.target.path_index=path;
+ nc.reference=ref;
+ return nc;
+ };
+
+ static SVGCommand PaintImageLoading(LoadIndex load_in,float ix, float iy,float iw,float ih,unsigned int ref, Corner corner=TopLeft)
+ {
+ SVGCommand nc;
+ nc.instr=DrawImageLoading;
+ nc.x=ix;
+ nc.y=iy;
+ nc.w=iw;
+ nc.h=ih;
+ nc.target.loadindex=load_in;
+ nc.reference=ref;
+ nc.corner=corner;
+ return nc;
+ };
+
+ static SVGCommand PaintImage(float ix, float iy,float iw,float ih,ImageIndex image_in,unsigned int ref, Corner corner=TopLeft)
{
- instr=DrawPath;
- x=ix;
- y=iy;
- w=iw;
- h=ih;
- target.path_index=path;
- reference=ref;
+ SVGCommand nc;
+ nc.instr=DrawImage;
+ nc.x=ix;
+ nc.y=iy;
+ nc.w=iw;
+ nc.h=ih;
+ nc.target.image=image_in;
+ nc.reference=ref;
+ nc.corner=corner;
+ return nc;
};
- SVGCommand(float ix, float iy,float iw,float ih,ImageIndex image_in,unsigned int ref)
+
+
+
+ static SVGCommand PaintTTchar(float ix, float iy,float iw,float ih,unsigned int ttchar_in)
{
- instr=DrawImage;
- x=ix;
- y=iy;
- w=iw;
- h=ih;
- target.image=image_in;
- reference=ref;
+ SVGCommand nc;
+ nc.instr=DrawTTchar;
+ nc.x=ix;
+ nc.y=iy;
+ nc.w=iw;
+ nc.h=ih;
+ nc.reference=0;
+ nc.target.ttchar=ttchar_in;
+ nc.corner=TopLeft;
+ return nc;
};
- SVGCommand(float ix, float iy,float iw,float ih,unsigned int ttchar_in)
+ static SVGCommand PaintClipping(float ix, float iy,float iw,float ih)
{
- instr=DrawTTchar;
- x=ix;
- y=iy;
- w=iw;
- h=ih;
- reference=0;
- target.ttchar=ttchar_in;
+ SVGCommand nc;
+ nc.instr=DrawClipping;
+ nc.x=ix;
+ nc.y=iy;
+ nc.w=iw;
+ nc.h=ih;
+ nc.reference=0;
+ nc.target.ttchar=0;
+ return nc;
};
- SVGCommand(float ix, float iy,wchar_t char_in,unsigned int ref)
+
+
+ static SVGCommand PaintGlyph(float ix, float iy,wchar_t char_in,unsigned int ref)
{
- instr=DrawGlyph;
- x=ix;
- y=iy;
- w=0;
- h=0;
- reference=ref;
- target.textchar=char_in;
+ SVGCommand nc;
+ nc.instr=DrawGlyph;
+ nc.x=ix;
+ nc.y=iy;
+ nc.w=0;
+ nc.h=0;
+ nc.reference=ref;
+ nc.target.textchar=char_in;
+ return nc;
};
bool Test(float tx,float ty,float tw, float th)
{
return (x==tox) && (toy==y) && (w==tx) && (h==ty);
}
+ bool Outside(float tx,float ty,float tw, float th)
+ {
+ return ((x+w)<tx) || ((y+h)<ty) || ((tx+tw) < x) || ((ty+th) < y);
+ }
+
unsigned int getRef(){return reference;};
ImageIndex getImageIndex() {
if (instr!=DrawImage) return 0;
else return target.image;
};
+ ImageIndex getLoadIndex() {
+ if (instr!=DrawImageLoading) return 0;
+ else return target.loadindex;
+ };
+
SVGCommandInstr instr;
float x,y,w,h;
unsigned int reference;
wchar_t textchar;
ImageIndex image;
unsigned int ttchar;
+ LoadIndex loadindex;
} target;
+ Corner corner;
+
};
class SurfaceVector;
+class VDR_ResponsePacket;
struct SurfaceCommands{
const SurfaceVector* surf;
virtual float getCharWidth(wchar_t c)=0;
virtual ImageIndex getJpegRef(const char* fileName, int *width,int *height);
+ virtual LoadIndex getTVMediaRef(TVMediaInfo& tvmedia,ImageIndex& image);
virtual ImageIndex getMonoBitmapRef(void *base,int width,int height);
virtual ImageIndex getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data);
virtual void imageUploadLine(ImageIndex index,unsigned int j,unsigned int width,void *data)=0;
void removeImageRef(const ImageIndex ref);
+ void removeLoadIndexRef(const LoadIndex ref);
unsigned int getColorRef(const Colour &c); //internally this is the same as getStyleRef
unsigned int getStyleRef(const DrawStyle &c);
virtual void removeStyleRef(unsigned int ref);
+ virtual void getScreenSize(int &width, int &height)=0;
+
+ // should be called from command thread
+ bool processReceivedPictures();
+
+ void receivePicture(VDR_ResponsePacket *vresp);
int charSet() {return 2;}; //UTF-8
void incImageRef(ImageIndex index);
unsigned int getImageRef(ImageIndex index);
virtual void destroyImageRef(ImageIndex index)=0;
+ void incLoadIndexRef(LoadIndex index);
+ unsigned int getLoadIndexRef(LoadIndex index);
+
+
virtual ImageIndex createJpeg(const char* fileName, int *width,int *height)=0;
virtual ImageIndex createMonoBitmap(void *base,int width,int height)=0;
virtual ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)=0;
+ virtual ImageIndex createPicture(unsigned char *data, unsigned int length)=0;
+
+ virtual LoadIndex loadTVMedia(TVMediaInfo& tvmedia);
+
+
map<ImageIndex,unsigned int> images_ref;
map<void *,ImageIndex> monobitmaps;
map<string,ImageIndex> jpegs;
+ map<TVMediaInfo,ImageIndex> tvmedias;
+
+
+
+ void setTVMedia(LoadIndex index, unsigned char * buffer, unsigned int length);
+ Mutex pict_lock_incoming; //locks
+ std::queue<VDR_ResponsePacket*> pict_incoming;
+ bool picture_update;
+
+
+ map<LoadIndex,unsigned int> loadindex_ref;
+ map<TVMediaInfo,LoadIndex> tvmedias_load;
+ map<LoadIndex,TVMediaInfo> tvmedias_load_inv;
+ map<LoadIndex,ImageIndex> tvmedias_loaded;
void incStyleRef(unsigned int index);
unsigned int getStyleRef(ImageIndex index);
types = NULL;
languages = NULL;
descriptions = NULL;
+
+ title = NULL;
}
RecInfo::~RecInfo()
delete[] types;
}
+ if (title) delete [] title;
+
timerStart = 0;
timerEnd = 0;
resumePoint = 0;
char** languages;
char** descriptions;
+ char *title;
+
void setNumComponents(ULONG);
void addComponent(ULONG componentNum, UCHAR tstream, UCHAR ttype, char* tlanguage, char* tdescription);
// addComponent accepts a pointer to a buffer that RecInfo will free, not the caller
#include "demuxer.h"
#include "demuxerts.h"
#include "command.h"
+#include "seriesinfo.h"
+#include "movieinfo.h"
Recording* Recording::recInfoFor = NULL;
RecInfo* Recording::recInfo = NULL;
+MovieInfo* Recording::movieInfo = NULL;
+SeriesInfo* Recording::seriesInfo = NULL;
Recording::Recording()
{
fileName = NULL;
index = -1;
markList = NULL;
+ movieID = 0;
+ seriesID = 0;
+ episodeID = 0;
}
Recording::~Recording()
recInfo = vdr->getRecInfo(fileName);
Log::getInstance()->log("Recording", Log::DEBUG, "Recording has loaded recInfo %p", recInfo);
- if (!VDR::getInstance()->isConnected()) Command::getInstance()->connectionLost();
+ if (!vdr->isConnected()) Command::getInstance()->connectionLost();
+
+ if (movieInfo) delete movieInfo;
+ if (seriesInfo) delete seriesInfo;
+
+ movieInfo = NULL;
+ seriesInfo = NULL;
+
+ vdr->getScraperEventType(fileName, movieID, seriesID, episodeID);
+ Log::getInstance()->log("Recording", Log::DEBUG, "Got Scraper EventType %d %d %d",
+ movieID, seriesID, episodeID);
+
+ if (!vdr->isConnected()) Command::getInstance()->connectionLost();
+
+ if (movieID != 0)
+ {
+ movieInfo = vdr->getScraperMovieInfo(movieID);
+ Log::getInstance()->log("Recording", Log::DEBUG, "Got Scraper MovieInfo ");
+ }
+ else if (seriesID != 0)
+ {
+ seriesInfo = vdr->getScraperSeriesInfo(seriesID, episodeID);
+ Log::getInstance()->log("Recording", Log::DEBUG, "Got Scraper SeriesInfo ");
+ }
+
+
+ if (!vdr->isConnected()) Command::getInstance()->connectionLost();
+
}
void Recording::dropRecInfo()
if (recInfo) delete recInfo;
recInfo = NULL;
recInfoFor = NULL;
+ if (movieInfo) delete movieInfo;
+ if (seriesInfo) delete seriesInfo;
+
+ movieInfo = NULL;
+ seriesInfo = NULL;
}
void Recording::loadMarks()
bool hasMarks();
MarkList* getMarkList();
+ int movieID;
+ int seriesID;
+ int episodeID;
+
static RecInfo* recInfo;
+ static MovieInfo* movieInfo;
+ static SeriesInfo* seriesInfo;
private:
Log* logger;
// else delete recInfo and reload for this recording
static Recording* recInfoFor;
+
MarkList* markList;
};
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "seriesinfo.h"
+
+
+EpisodeInfo::EpisodeInfo() {
+ name="";
+ firstAired="";
+ guestStars="";
+ overview="";
+
+ rating=0.;
+ season=0;
+ episodeid=0;
+ number=0;
+}
+
+EpisodeInfo::~EpisodeInfo() {
+
+}
+
+SeriesInfo::SeriesInfo()
+{
+ id=0;
+
+
+
+}
+
+
+
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SERIESINFO_H
+#define SERIESINFO_H
+
+#include "tvmedia.h"
+#include <string>
+
+class EpisodeInfo {
+public:
+ EpisodeInfo();
+ ~EpisodeInfo();
+
+ int episodeid;
+ int number;
+ int season;
+ std::string name;
+ std::string firstAired;
+ std::string guestStars;
+ std::string overview;
+ float rating ;
+ TVMedia image;
+
+
+};
+
+class SeriesInfo {
+public:
+ SeriesInfo();
+
+ int id;
+
+
+ std::string name;
+ std::string overview;
+ std::string firstAired;
+ std::string network;
+ std::string genre;
+ double rating;
+ std::string status;
+ EpisodeInfo episode; // Image 0
+
+
+
+
+ Actors actors; // Image 1
+ TVMedias posters; // Image 2
+ TVMedias banners; // Image 3
+ TVMedias fanart; // Image 4
+ TVMedia seasonposter; // Image 5
+};
+#endif
{
osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
ImageIndex ii=(*itty).getImageIndex();
- if (ii) osd->removeImageRef(ii);
+ if (ii) {
+ osd->removeImageRef(ii);
+ }
+ LoadIndex li=(*itty).getLoadIndex();
+ if (li) osd->removeLoadIndexRef(li);
itty++;
}
}
while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
{
unsigned int ref=osd->getStyleRef(c);
- commands.push_back(SVGCommand(x+shift,y,*tempo,ref));
+ commands.push_back(SVGCommand::PaintGlyph(x+shift,y,*tempo,ref));
shift+=osd->getCharWidth(*tempo);
length -= num_bytes;
run += num_bytes;
{
command_mutex.Lock();
ImageIndex image=osd->getJpegRef(fileName,width,height);
- commands.push_back(SVGCommand(x,y,*width,*height,image,0));
+ commands.push_back(SVGCommand::PaintImage(x,y,*width,*height,image,0));
+ command_mutex.Unlock();
+}
+
+void SurfaceVector::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner)
+{
+ command_mutex.Lock();
+ ImageIndex image=0;
+ LoadIndex load_index=osd->getTVMediaRef(tvmedia,image);
+ if (image) {
+ //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image);
+ commands.push_back(SVGCommand::PaintImage(x,y,width,height,image,0,corner));
+ } else {
+
+ commands.push_back(SVGCommand::PaintImageLoading(load_index,x,y,width,height,0,corner));
+ //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image);
+ }
+ command_mutex.Unlock();
+}
+
+void SurfaceVector::drawClippingRectangle(float x, float y, float w, float h)
+{
+ command_mutex.Lock();
+ commands.push_back(SVGCommand::PaintClipping((float)x,(float)y,(float)w,(float)h));
command_mutex.Unlock();
}
command_mutex.Lock();
removeCommands(x,y,width,height); // remove commands below the box
unsigned int ref=osd->getStyleRef(c);
- commands.push_back(SVGCommand(x,y,width,height,Rectangle,ref));
+ commands.push_back(SVGCommand::PaintPath(x,y,width,height,Rectangle,ref));
command_mutex.Unlock();
return 1;
{
command_mutex.Lock();
unsigned int ref=osd->getStyleRef(c);
- commands.push_back(SVGCommand(x1,y,x2-x1,1,HorzLine,ref));
+ commands.push_back(SVGCommand::PaintPath(x1,y,x2-x1,1,HorzLine,ref));
command_mutex.Unlock();
}
void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c){
command_mutex.Lock();
unsigned int ref=osd->getStyleRef(c);
- commands.push_back(SVGCommand(x,y1,1,y2-y1,VertLine,ref));
+ commands.push_back(SVGCommand::PaintPath(x,y1,1,y2-y1,VertLine,ref));
command_mutex.Unlock();
}
ty*=scaley;
tw*=scalex;
th*=scaley;
- SVGCommand temp=SVGCommand(tx,ty,tw,th,image,0);
+ SVGCommand temp=SVGCommand::PaintImage(tx,ty,tw,th,image,0);
commands.push_back(temp);
command_mutex.Unlock();
}
void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw){
if (!fastdraw) command_mutex.Lock();
unsigned int ref=osd->getStyleRef(c);
- commands.push_back(SVGCommand(x,y,1,1,Point,ref));
+ commands.push_back(SVGCommand::PaintPath(x,y,1,1,Point,ref));
if (!fastdraw) command_mutex.Unlock();
}
void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour)
command_mutex.Lock();
ImageIndex image=osd->getMonoBitmapRef(base,width,height);
unsigned int ref=osd->getStyleRef(nextColour);
- commands.push_back(SVGCommand(dx,dy,height,width,image,ref));
+ commands.push_back(SVGCommand::PaintImage(dx,dy,height,width,image,ref));
command_mutex.Unlock();
}
list<SVGCommand>::iterator itty=commands.begin();
while (itty!=commands.end())
{
- if ((*itty).Test(x,y,width,height) ) {
+ if ((*itty).Test(x,y,width,height) && (*itty).instr != DrawClipping) {
osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
ImageIndex ii=(*itty).getImageIndex();
if (ii) osd->removeImageRef(ii);
+ LoadIndex li=(*itty).getLoadIndex();
+ if (li) osd->removeLoadIndexRef(li);
itty=commands.erase(itty);
} else {
itty++;
itty++;
}
}
- commands.push_back(SVGCommand(ox,oy,x,y,c.getInternal()));
+ commands.push_back(SVGCommand::PaintTTchar(ox,oy,x,y,c.getInternal()));
command_mutex.Unlock();
}
int drawTextCentre(const char* text, int x, int y, const DrawStyle& c);
void drawJpeg(const char *fileName,int x, int y,int *width, int *height);
+ // set width and height to zero, if the original size is wanted, if one index is non zero,
+ // the images is scaled with correct aspect ratio, if both are non zero both are scaled
+ void drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner=TopLeft);
+ // set w and h to 0, for unsetting clipping, use correct x and y parameter so that cleanup of commands works
+ void drawClippingRectangle(float x, float y, float w, float h);
int create(UINT width, UINT height);
void display();
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "tvmedia.h"
+#include "movieinfo.h"
+#include "seriesinfo.h"
+
+
+TVMediaInfo::TVMediaInfo()
+{
+ type=2; // movie or series
+ primary_id=0; //movie or series_id
+ secondary_id=0; //0 or episode id
+ type_pict=-1; // 0 full info, 1 poster, 2 poster banner, 3 poster thumb
+ container=-1; // indices the dataelements with picture in movieinfo or seriesinfo
+ container_member=-1; // index into the container
+}
+
+
+
+TVMediaInfo::TVMediaInfo(const TVMediaInfo& info)
+{
+ type=info.type; // movie or series
+ primary_id=info.primary_id; //movie or series_id
+ secondary_id=info.secondary_id; //0 or episode id
+ type_pict=info.type_pict; // 0 full info, 1 poster, 2 poster banner, 3 poster thumb
+ container=info.container; // indices the dataelements with picture in movieinfo or seriesinfo
+ container_member=info.container_member; // index into the container
+
+}
+
+void TVMediaInfo::setMovieInfo(const MovieInfo * mi)
+{
+ type=1; // movie or series
+ primary_id=mi->id; //movie or series_id
+ secondary_id=0; //0 or episode id
+}
+
+void TVMediaInfo::setSeriesInfo(const SeriesInfo * si)
+{
+ type=0; // movie or series
+ primary_id=si->id; //movie or series_id
+ secondary_id=si->episode.episodeid; //0 or episode id
+}
+
+bool operator<(const TVMediaInfo& rhs, const TVMediaInfo& lhs)
+{
+ if (rhs.type==lhs.type) {
+ if (rhs.primary_id==lhs.primary_id) {
+ if (rhs.secondary_id==lhs.secondary_id) {
+ if (rhs.type_pict==lhs.type_pict) {
+ if (rhs.container==lhs.container) {
+ return rhs.container_member<lhs.container_member;
+ } else {
+ return rhs.container<lhs.container;
+ }
+
+
+ } else {
+ return rhs.type_pict<lhs.type_pict;
+ }
+
+ } else {
+ return rhs.secondary_id<lhs.secondary_id;
+ }
+
+ } else {
+ return rhs.primary_id<lhs.primary_id;
+ }
+
+ } else {
+ return rhs.type < lhs.type;
+ }
+}
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef TVMEDIA_H
+#define TVMEDIA_H
+
+#include "defines.h"
+#include <vector>
+#include <string>
+
+class MovieInfo;
+class SeriesInfo;
+
+class TVMediaInfo
+{
+friend class VDR;
+public:
+ TVMediaInfo();
+ TVMediaInfo(const TVMediaInfo& info);
+
+ friend bool operator<(const TVMediaInfo& rhs, const TVMediaInfo& lhs);
+
+ void setSeasonThumb() { type_pict=2; container=0; container_member=0;};
+ void setPosterThumb() { type_pict=1; container=0; container_member=0;};
+ void setElement(int cont,int memb) { type_pict=0; container=cont; container_member=memb;};
+ void setMovieInfo(const MovieInfo * mi);
+ void setSeriesInfo(const SeriesInfo * si);
+
+private:
+ int type; // movie or series
+ int primary_id; //movie or series_id
+ int secondary_id; //0 or episode id
+ int type_pict; // 0 full info, 1 poster thumb, 2 season thumb
+ int container; // indices the dataelements with picture in movieinfo or seriesinfo
+ int container_member; // index into the container
+};
+
+struct TVMedia
+{
+ unsigned int width;
+ unsigned int height;
+
+ // no filename, file handling is only on the server
+ TVMediaInfo info;
+
+};
+
+typedef std::vector<TVMedia> TVMedias;
+
+struct Actor
+{
+ std::string name;
+ std::string role;
+ TVMedia thumb;
+};
+
+typedef std::vector<Actor> Actors;
+
+#endif
if (success)
{
logger->log("VConnect", Log::DEBUG, "Connected ok, doing login");
- unsigned int version_server,version_client;
- success = vdr->doLogin(&version_server,&version_client);
+ unsigned int version_server_min,version_server_max,version_client;
+ success = vdr->doLogin(&version_server_min,&version_server_max,&version_client);
if (!success)
{
vdr->disconnect();
- if (version_server!=version_client) {
+ if (version_server_min >version_client || version_client > version_server_max) {
char buffer[1024];
- sprintf(buffer,"Protocoll mismatch s: %x c: %x",version_server,version_client);
+ sprintf(buffer,"Protocol mismatch s min: %x s max: %x c: %x",version_server_min,version_server_max,version_client);
setOneLiner(buffer);
} else {
setOneLiner(tr("Login failed"));
#include "vdrcommand.h"
#include "video.h"
#include "osd.h"
+#include "movieinfo.h"
+#include "seriesinfo.h"
-#define VOMP_PROTOCOLL_VERSION 0x00000301
+
+#define VOMP_PROTOCOLL_VERSION 0x00000302
VDR* VDR::instance = NULL;
//prepare a request
// Data was read
channelID = ntohl(channelID);
-
+
if (channelID == CHANNEL_REQUEST_RESPONSE)
{
if (!tcp->readData((UCHAR*)&requestID, sizeof(ULONG))) break;
delete vresp;
}
}
- else if (channelID == CHANNEL_STREAM)
+ else if (channelID == CHANNEL_STREAM || channelID == CHANNEL_TVMEDIA)
{
if (!tcp->readData((UCHAR*)&streamID, sizeof(ULONG))) break;
streamID = ntohl(streamID);
}
vresp = new VDR_ResponsePacket();
- vresp->setStream(streamID, flag, userData, userDataLength);
-// logger->log("VDR", Log::DEBUG, "Rxd a stream packet, streamID=%lu, flag=%lu, len=%lu", streamID, flag, userDataLength);
+ vresp->setStream(streamID, flag, userData, userDataLength, channelID);
+ //logger->log("VDR", Log::DEBUG, "Rxd a stream packet, streamID=%lu, flag=%lu, len=%lu", streamID, flag, userDataLength);
if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
{
}
edLock();
}
- else if (vdrpr->receiverChannel == CHANNEL_STREAM)
+ else if (vdrpr->receiverChannel == CHANNEL_STREAM || vdrpr->receiverChannel == CHANNEL_TVMEDIA)
{
vresp = new VDR_ResponsePacket();
- vresp->setStream(vdrpr->streamID, 2 /* connection-lost flag */ , NULL, 0);
+ vresp->setStream(vdrpr->streamID, 2 /* connection-lost flag */ , NULL, 0, vdrpr->receiverChannel);
logger->log("VDR", Log::DEBUG, "Timeouts: created blank response packet for streamid %lu", vdrpr->streamID);
edUnlock();
if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
// Is vresp for vdrpr ?
ULONG packetChannel = vresp->getChannelID();
+ //logger->log("VDR", Log::DEBUG, "TVMedia debug %d %d %x", vdrpr->receiverChannel,packetChannel,vdrpr);
if (vdrpr->receiverChannel != packetChannel) return false;
if (packetChannel == CHANNEL_REQUEST_RESPONSE)
else if (packetChannel == CHANNEL_STREAM)
{
if (vdrpr->streamID == vresp->getStreamID()) return true;
+ } else if (packetChannel == CHANNEL_TVMEDIA)
+ { //We want them all
+ return true;
}
return false;
// Here VDR takes a break for the VDR_PacketReceiver helper class
-bool VDR_PacketReceiver::call(void* userTag)
+bool VDR_PacketReceiver::call(void* userTag, bool & deleteme)
{
if (receiverChannel == VDR::CHANNEL_REQUEST_RESPONSE)
{
// VDR::RequestResponse will be blocking waiting for this to happen.
// That function has a pointer to this object and can read save_vresp.
save_vresp = (VDR_ResponsePacket*)userTag;
+ deleteme=false;
return true; // Signals ED to remove edr from receivers and wake up edr thread
}
VDR_ResponsePacket* vresp = (VDR_ResponsePacket*)userTag;
streamReceiver->streamReceive(vresp->getFlag(), vresp->getUserData(), vresp->getUserDataLength());
delete vresp;
+ deleteme=false;
return false;
}
+ if (receiverChannel == VDR::CHANNEL_TVMEDIA)
+ {
+ // It's TVMedia
+ VDR_ResponsePacket* vresp = (VDR_ResponsePacket*)userTag;
+ Log::getInstance()->log("VDR", Log::DEBUG, "TVMedia Pictures arrived VDR");
+ OsdVector *osd=dynamic_cast<OsdVector*>(Osd::getInstance());
+ if (osd) osd->receivePicture(vresp);
+ else delete vresp; //nonsense
+ deleteme=false;
+ return true;
+ }
+
abort(); // unknown receiverChannel, should not happen
}
/////////////////////////////////////////////////////////////////////////////
-int VDR::doLogin(unsigned int* v_server,unsigned int* v_client)
+int VDR::doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigned int* v_client)
{
VDR_RequestPacket vrp;
if (!vrp.init(VDR_LOGIN, true, 6)) return 0;
long vdrTimeOffset = vresp->extractLONG();
logger->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);
- unsigned int version=vresp->extractULONG();
+ unsigned int version_min=vresp->extractULONG();
- *v_server=version;
+ *v_server_min=version_min;
+ unsigned int version_max=vresp->extractULONG();
+ *v_server_max=version_max;
*v_client=VOMP_PROTOCOLL_VERSION;
delete vresp;
- if (version!=VOMP_PROTOCOLL_VERSION) {
+ if ((version_min > VOMP_PROTOCOLL_VERSION)
+ || (version_max < VOMP_PROTOCOLL_VERSION) ) {
return 0;
}
}
recInfo->fps=vresp->extractdouble();
+ recInfo->title=vresp->extractString();
recInfo->print();
logger->log("VDR", Log::DEBUG, "VDR shutdown");
}
+
+void VDR::getScraperEventType(char * fileName, int & movieID,
+ int & seriesID, int & episodeID )
+{
+ movieID = 0;
+ seriesID = 0;
+ episodeID = 0;
+ VDR_RequestPacket vrp;
+ if (!vrp.init(VDR_GETRECSCRAPEREVENTTYPE, true, strlen(fileName) + 1)) return;
+ if (!vrp.addString(fileName)) return ;
+ Log::getInstance()->log("Recording", Log::DEBUG, "Before Response ");
+ VDR_ResponsePacket* vresp = RequestResponse(&vrp);
+ Log::getInstance()->log("Recording", Log::DEBUG, "After Response ");
+ if (vresp->noResponse()) { delete vresp; return ; }
+ int type = vresp->extractUCHAR();
+ if (type == 0) //serie
+ {
+ seriesID = vresp->extractLONG();
+ episodeID = vresp->extractLONG();
+ } else if (type == 1) //movie
+ {
+ movieID = vresp->extractLONG();
+ }
+ delete vresp;
+
+}
+
+MovieInfo *VDR::getScraperMovieInfo(int movieID)
+{
+ VDR_RequestPacket vrp;
+ if (!vrp.init(VDR_GETSCRAPERMOVIEINFO, false, 0)) return NULL;
+ if (!vrp.addULONG(movieID)) return NULL;
+ VDR_ResponsePacket* vresp = RequestResponse(&vrp);
+ if (vresp->noResponse()) { delete vresp; return NULL; }
+ MovieInfo * movieinf= new MovieInfo();
+
+ movieinf->id=movieID;
+ movieinf->title = vresp->extractStdString();
+ movieinf->originalTitle = vresp->extractStdString();
+ movieinf->tagline = vresp->extractStdString();
+ movieinf->overview = vresp->extractStdString();
+ movieinf->adult = vresp->extractUCHAR();
+ movieinf->collectionName = vresp->extractStdString();
+
+ movieinf->budget = vresp->extractLONG();
+ movieinf->revenue = vresp->extractLONG();
+ movieinf->genres = vresp->extractStdString();
+ movieinf->homepage = vresp->extractStdString();
+ movieinf->releaseDate = vresp->extractStdString();
+ movieinf->runtime = vresp->extractLONG();
+ movieinf->popularity = vresp->extractdouble();
+ movieinf->voteAverage = vresp->extractdouble();
+ movieinf->poster.width = vresp->extractULONG();
+ movieinf->poster.height = vresp->extractULONG();
+ movieinf->poster.info.setMovieInfo(movieinf);
+ movieinf->poster.info.setElement(0,0);
+ movieinf->fanart.width = vresp->extractULONG();
+ movieinf->fanart.height = vresp->extractULONG();
+ movieinf->fanart.info.setMovieInfo(movieinf);
+ movieinf->fanart.info.setElement(1,0);
+ movieinf->collectionPoster.width = vresp->extractULONG();
+ movieinf->collectionPoster.height = vresp->extractULONG();
+ movieinf->collectionPoster.info.setMovieInfo(movieinf);
+ movieinf->collectionPoster.info.setElement(2,0);
+ movieinf->collectionFanart.width = vresp->extractULONG();
+ movieinf->collectionFanart.height = vresp->extractULONG();
+ movieinf->collectionFanart.info.setMovieInfo(movieinf);
+ movieinf->collectionFanart.info.setElement(3,0);
+ ULONG num_actors = vresp->extractULONG();
+ movieinf->actors.clear();
+ movieinf->actors.reserve(num_actors);
+ for (ULONG acty=0; acty < num_actors; acty++) {
+ Actor new_act;
+ new_act.name = vresp->extractStdString();
+ new_act.role = vresp->extractStdString();
+ new_act.thumb.width = vresp->extractULONG();
+ new_act.thumb.height = vresp->extractULONG();
+ new_act.thumb.info.setMovieInfo(movieinf);
+ new_act.thumb.info.setElement(4,acty);
+ movieinf->actors.push_back(new_act);
+ }
+
+
+ delete vresp;
+ return movieinf;
+
+}
+
+SeriesInfo *VDR::getScraperSeriesInfo(int seriesID, int episodeID)
+{
+ VDR_RequestPacket vrp;
+ if (!vrp.init(VDR_GETSCRAPERSERIESINFO, false, 0)) return NULL;
+ if (!vrp.addULONG(seriesID)) return NULL;
+ if (!vrp.addULONG(episodeID)) return NULL;
+
+ VDR_ResponsePacket* vresp = RequestResponse(&vrp);
+ if (vresp->noResponse()) { delete vresp; return 0; }
+ SeriesInfo * seriesinf= new SeriesInfo();
+
+ seriesinf->id=seriesID;
+
+
+ seriesinf->name = vresp->extractStdString();
+ seriesinf->overview = vresp->extractStdString();
+ seriesinf->firstAired = vresp->extractStdString();
+ seriesinf->network = vresp->extractStdString();
+ seriesinf->genre = vresp->extractStdString();
+ seriesinf->rating = vresp->extractdouble();
+ seriesinf->status = vresp->extractStdString();
+
+
+ seriesinf->episode.episodeid=episodeID;
+ seriesinf->episode.number = vresp->extractLONG();
+ seriesinf->episode.season = vresp->extractLONG();
+ seriesinf->episode.name = vresp->extractStdString();
+ seriesinf->episode.firstAired = vresp->extractStdString();
+ seriesinf->episode.guestStars = vresp->extractStdString();
+ seriesinf->episode.overview = vresp->extractStdString();
+ seriesinf->episode.rating = vresp->extractdouble();
+ seriesinf->episode.image.width = vresp->extractULONG();
+ seriesinf->episode.image.height = vresp->extractULONG();
+ seriesinf->episode.image.info.setSeriesInfo(seriesinf);
+ seriesinf->episode.image.info.setElement(0,0);
+
+
+ ULONG num_actors = vresp->extractULONG();
+ seriesinf->actors.clear();
+ seriesinf->actors.reserve(num_actors);
+ for (ULONG acty=0; acty < num_actors; acty++) {
+ Actor new_act;
+ new_act.name = vresp->extractStdString();
+ new_act.role = vresp->extractStdString();
+ new_act.thumb.width = vresp->extractULONG();
+ new_act.thumb.height = vresp->extractULONG();
+ new_act.thumb.info.setSeriesInfo(seriesinf);
+ new_act.thumb.info.setElement(1,acty);
+ seriesinf->actors.push_back(new_act);
+ }
+ ULONG num_posters = vresp->extractULONG();
+ for (ULONG medias = 0; medias < num_posters; medias++ ) {
+ TVMedia media;
+ media.info.setSeriesInfo(seriesinf);
+ media.info.setElement(2,medias);
+ media.width = vresp->extractULONG();
+ media.height = vresp->extractULONG();
+ seriesinf->posters.push_back(media);
+ }
+
+ ULONG num_banners = vresp->extractULONG();
+ for (ULONG medias = 0; medias < num_banners; medias++ ) {
+ TVMedia media;
+ media.info.setSeriesInfo(seriesinf);
+ media.info.setElement(3,medias);
+ media.width = vresp->extractULONG();
+ media.height = vresp->extractULONG();
+ seriesinf->banners.push_back(media);
+ }
+ ULONG num_fanarts = vresp->extractULONG();
+ for (ULONG medias = 0; medias < num_fanarts; medias++ ) {
+ TVMedia media;
+ media.info.setSeriesInfo(seriesinf);
+ media.info.setElement(4,medias);
+ media.width = vresp->extractULONG();
+ media.height = vresp->extractULONG();
+ seriesinf->fanart.push_back(media);
+ }
+ seriesinf->seasonposter.width = vresp->extractULONG();
+ seriesinf->seasonposter.height = vresp->extractULONG();
+ seriesinf->seasonposter.info.setSeriesInfo(seriesinf);
+ seriesinf->seasonposter.info.setElement(5,0);
+
+ delete vresp;
+ return seriesinf;
+
+}
+
+ULONG VDR::loadTVMedia(TVMediaInfo& tvmedia)
+{
+
+ VDR_RequestPacket vrp;
+
+ if (!vrp.init(VDR_LOADTVMEDIA, false, 0)) return -1;
+ if (!vrp.addULONG(tvmedia.type)) return -1;
+ if (!vrp.addULONG(tvmedia.primary_id)) return -1;
+ if (!vrp.addULONG(tvmedia.secondary_id)) return -1;
+ if (!vrp.addULONG(tvmedia.type_pict)) return -1;
+ if (!vrp.addULONG(tvmedia.container)) return -1;
+ if (!vrp.addULONG(tvmedia.container_member)) return -1;
+ Log::getInstance()->log("VDR", Log::DEBUG, "TVMedia with ID %d %d; %d %d %d %d;%d",
+ tvmedia.primary_id,tvmedia.secondary_id,tvmedia.type,tvmedia.type_pict,
+ tvmedia.container,tvmedia.container_member,vrp.getSerial());
+
+
+ VDR_PacketReceiver* vdrpr = new VDR_PacketReceiver();
+ vdrpr->receiverChannel = VDR::CHANNEL_TVMEDIA;
+ vdrpr->streamID = vrp.getSerial();
+ vdrpr->streamReceiver = NULL;
+ edRegister(vdrpr);
+
+
+ VDR_ResponsePacket* vresp = RequestResponse(&vrp);
+ //if (vresp->noResponse()) { delete vresp; return -1; }
+ delete vresp;
+
+ return vrp.getSerial();
+}
#include "eventdispatcher.h"
#include "i18n.h"
#include "log.h"
+#include "osdvector.h"
class TCP;
class Log;
class VDR_RequestPacket;
class VDR_ResponsePacket;
class SerializeBuffer;
+class MovieInfo;
+class SeriesInfo;
+
using namespace std;
class VDR_PacketReceiver : public EDReceiver // implementation in vdr.cc
{
public:
- virtual bool call(void* userTag);
+ virtual bool call(void* userTag, bool & deleteme);
friend class VDR;
protected:
const static ULONG CHANNEL_STREAM = 2;
const static ULONG CHANNEL_KEEPALIVE = 3;
const static ULONG CHANNEL_NETLOG = 4;
+ const static ULONG CHANNEL_TVMEDIA = 5;
VDR();
~VDR();
// configSave
// setEventTimer
- int doLogin(unsigned int* v_server,unsigned int* v_client);
+ int doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigned int* v_client);
bool getRecordingsList(RecMan* recman);
RecInfo* getRecInfo(char* fileName);
int deleteRecording(char* fileName);
virtual int getMediaInfo(ULONG channel, struct MediaInfo * result);
virtual int closeMediaChannel(ULONG channel);
+ //TV Scraper support
+ void getScraperEventType(char * fileName, int & movieID, int & seriesID, int & episodeID);
+ MovieInfo *getScraperMovieInfo(int movieID);
+ SeriesInfo *getScraperSeriesInfo(int seriesID, int episodeID);
+ ULONG loadTVMedia(TVMediaInfo& tvmedia);
+
I18n::lang_code_list getLanguageList();
int getLanguageContent(const string code, I18n::trans_table&);
const static ULONG VDR_GETMEDIABLOCK = 32;
const static ULONG VDR_GETMEDIAINFO = 35;
const static ULONG VDR_CLOSECHANNEL = 36;
+const static ULONG VDR_GETRECSCRAPEREVENTTYPE = 38;
+const static ULONG VDR_GETSCRAPERMOVIEINFO = 39;
+const static ULONG VDR_GETSCRAPERSERIESINFO = 40;
+const static ULONG VDR_LOADTVMEDIA = 41;
const static ULONG VDR_SHUTDOWN = 666;
class VDR_Command : public SerializableList {
userDataLength = tuserDataLength;
}
-void VDR_ResponsePacket::setStream(ULONG tstreamID, ULONG tflag, UCHAR* tuserData, ULONG tuserDataLength)
+void VDR_ResponsePacket::setStream(ULONG tstreamID, ULONG tflag, UCHAR* tuserData, ULONG tuserDataLength, ULONG tchannelID)
{
- channelID = VDR::CHANNEL_STREAM;
+ channelID = tchannelID;
streamID = tstreamID;
flag = tflag;
userData = tuserData;
else return 0;
}
+std::string VDR_ResponsePacket::extractStdString()
+{
+ if (serverError()) return NULL;
+
+ int length = strlen((char*)&userData[packetPos]);
+ if ((packetPos + length) > userDataLength) return std::string("");
+ const char * dest_str=(char*)&userData[packetPos];
+ packetPos += length + 1;
+ return dest_str;
+}
+
char* VDR_ResponsePacket::extractString()
{
if (serverError()) return NULL;
#include <stdlib.h>
#include <string.h>
+#include <string>
#include "defines.h"
~VDR_ResponsePacket();
void setResponse(ULONG requestID, UCHAR* packet, ULONG packetLength);
- void setStream(ULONG streamID, ULONG flag, UCHAR* packet, ULONG packetLength);
+ void setStream(ULONG streamID, ULONG flag, UCHAR* packet, ULONG packetLength, ULONG tchannelID);
bool noResponse() { return (userData == NULL); };
int serverError();
ULONG getFlag() { return flag; }
char* extractString();
+ std::string extractStdString();
UCHAR extractUCHAR();
ULONG extractULONG();
ULLONG extractULLONG();
}
- Log::getInstance()->log("Video", Log::DEBUG, "mark2 ");
+
if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
clock_mutex.Unlock();
- Log::getInstance()->log("Video", Log::DEBUG, "mark1 ");
+
if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
clock_mutex.Unlock();
DeAllocateCodecsOMX();
- Log::getInstance()->log("Video", Log::DEBUG, "mark1 special ");
+
if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
clock_mutex.Unlock();
DeAllocateCodecsOMX();
- Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
-
-
/* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
if (error!=OMX_ErrorNone){
Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
#include "recording.h"
#include "message.h"
#include "log.h"
+#include "wmovieview.h"
+#include "wseriesview.h"
+#include "wpictureview.h"
VRecording::VRecording(RecMan* trecman, Recording* trec)
{
rec = trec;
recman = trecman;
+ buttons = true;
Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
rec->loadRecInfo();
Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
- setSize(570, 420);
- createBuffer();
+
if (Video::getInstance()->getFormat() == Video::PAL)
{
- setPosition(80, 70);
+ setSize(640, 500);
+ createBuffer();
}
else
{
- setPosition(70, 35);
+ setSize(560, 400);
+ createBuffer();
}
+ setPosition(40, 40);
setTitleBarOn(1);
setBorderOn(1);
- setTitleText(rec->getProgName());
+ if (rec->recInfo && strlen(rec->recInfo->title))
+ setTitleText(rec->recInfo->title);
+ else
+ setTitleText(rec->getProgName());
setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
- summary.setPosition(10, 30 + 5);
- summary.setSize(area.w - 20, area.h - 30 - 15 - 50);
- summary.setParaMode(true);
+ tabbar.setPosition(10+130+10, 30 + 5);
+ tabbar.setSize(area.w - 20-10-130, area.h - 30 - 10);
+ add(&tabbar);
+
+
+
- if (rec->recInfo &&strlen(rec->recInfo->summary))
- summary.setText(rec->recInfo->summary);
+ WTextbox * summary=new WTextbox();
+ summary->setParaMode(true);
+
+ if (rec->recInfo && strlen(rec->recInfo->summary))
+ summary->setText(rec->recInfo->summary);
else
- summary.setText(tr("Summary unavailable"));
+ summary->setText(tr("Summary unavailable"));
+
+ OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
+
+ tabbar.addTab(tr("EPG"), summary);
+ if (rec->movieInfo) {
+ WMovieView *movieview = new WMovieView(rec->movieInfo);
+ movieview->setParaMode(true);
+ tabbar.addTab(tr("TheTVDB Info"), movieview);
+ if (osdv) {
+ if (rec->movieInfo->actors.size() > 0 && osdv)
+ {
+ WActorGallery *gallery= new WActorGallery(rec->movieInfo->actors);
+ tabbar.addTab(tr("Cast"),gallery);
+ }
+ WArtworkGallery *artgallery= new WArtworkGallery(*rec->movieInfo);
+ tabbar.addTab(tr("Gallery"),artgallery);
+ }
+ } else if (rec->seriesInfo) {
+ WSeriesView *seriesview = new WSeriesView(rec->seriesInfo);
+ seriesview->setParaMode(true);
+ tabbar.addTab(tr("TheTVDB Info"), seriesview);
+ if (osdv) {
+ if (rec->seriesInfo->actors.size() > 0 && osdv)
+ {
+ WActorGallery *gallery= new WActorGallery(rec->seriesInfo->actors);
+ tabbar.addTab(tr("Cast"),gallery);
+ }
+ WArtworkGallery *artgallery= new WArtworkGallery(*rec->seriesInfo);
+ tabbar.addTab(tr("Gallery"),artgallery);
+ }
+
+ }
+
- add(&summary);
int sfh = getFontHeight();
buttonRegion.x = 10;
- buttonRegion.y = area.h - 40;
- buttonRegion.w = 550;
- buttonRegion.h = sfh;
+ buttonRegion.y = 10+30;
+ buttonRegion.w = 130;
+ buttonRegion.h = sfh*2*last;
button[PLAY].setText(tr("Play"));
button[RESUME].setText(tr("Resume"));
button[MOVE].setText(tr("Move"));
button[A_DELETE].setText(tr("Delete"));
- for (int i=PLAY, hor=10; i<last; i++, hor+= 140)
+ for (int i=PLAY, ver=10+30; i<last; i++, ver+= sfh*2)
{
- button[i].setPosition(hor, area.h - 40);
+ button[i].setPosition(10, ver);
button[i].setSize(130, sfh);
add(&button[i]);
}
selected = RESUME;
button[selected].setActive(1);
+ tabbar.activateFocus(false);
}
VRecording::~VRecording()
void VRecording::draw()
{
TBBoxx::draw();
+ OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
+ if (osdv) {
+ TVMedia poster;
+ if (rec->movieInfo) {
+ poster=rec->movieInfo->poster;
+ }
+ if (rec->seriesInfo) {
+ if (rec->seriesInfo->seasonposter.height) {
+ poster=rec->seriesInfo->seasonposter;
+ }
+ else
+ if (rec->seriesInfo->posters.size()) {
+ poster=rec->seriesInfo->posters[0];
+ }
+ }
+ if (poster.height) {
+ // float aspect=((float)poster.height)/((float)poster.width)/Osd::getInstance()->getPixelAspect();
+ drawTVMedia(poster.info,buttonRegion.x,
+ buttonRegion.y+buttonRegion.h,
+ buttonRegion.w,/*buttonRegion.w*aspect*/0.f);
+ }
+ }
+
}
int VRecording::handleCommand(int command)
{
- switch(command)
- {
- case Remote::LEFT:
- case Remote::DF_LEFT:
- case Remote::DF_UP:
- case Remote::UP:
- {
- moveCursor(LEFT);
- return 2;
- }
- case Remote::RIGHT:
- case Remote::DF_RIGHT:
- case Remote::DF_DOWN:
- case Remote::DOWN:
- {
- moveCursor(RIGHT);
- return 2;
- }
- case Remote::OK:
- {
+ if (command==Remote::BACK) {
+ return 4;
+ }
+ if (buttons) {
+ switch(command)
+ {
+ case Remote::DF_UP:
+ case Remote::UP:
+ {
+ moveCursor(LEFT);
+ return 2;
+ }
- if (selected == PLAY)
- {
- Message* m = new Message(); // Must be done after this view deleted
- m->from = this;
- m->to = vRecList;
- m->message = Message::PLAY_SELECTED_RECORDING;
- Command::getInstance()->postMessageNoLock(m);
- return 4;
- }
+ case Remote::DF_DOWN:
+ case Remote::DOWN:
+ {
+ moveCursor(RIGHT);
+ return 2;
+ }
+ case Remote::LEFT:
+ case Remote::DF_LEFT:
+ case Remote::RIGHT:
+ case Remote::DF_RIGHT:
+ {
+ buttons = false;
+ button[selected].setActive(0);
+ tabbar.activateFocus(true);
+ button[selected].draw();
+ tabbar.draw();
+ BoxStack::getInstance()->update(this);
+ return 2;
+ }
+ case Remote::OK:
+ {
- if (selected == RESUME)
- {
- Message* m = new Message(); // Must be done after this view deleted
- m->from = this;
- m->to = vRecList;
- m->message = Message::RESUME_SELECTED_RECORDING;
- Command::getInstance()->postMessageNoLock(m);
- return 4;
- }
+ if (selected == PLAY)
+ {
+ Message* m = new Message(); // Must be done after this view deleted
+ m->from = this;
+ m->to = vRecList;
+ m->message = Message::PLAY_SELECTED_RECORDING;
+ Command::getInstance()->postMessageNoLock(m);
+ return 4;
+ }
- if (selected == MOVE)
- {
- VRecMove* vrm = new VRecMove(recman);
- vrm->setParent(this);
- vrm->draw();
- BoxStack::getInstance()->add(vrm);
- BoxStack::getInstance()->update(vrm);
- return 2;
- }
+ if (selected == RESUME)
+ {
+ Message* m = new Message(); // Must be done after this view deleted
+ m->from = this;
+ m->to = vRecList;
+ m->message = Message::RESUME_SELECTED_RECORDING;
+ Command::getInstance()->postMessageNoLock(m);
+ return 4;
+ }
- if (selected == A_DELETE)
- {
- VQuestion* v = new VQuestion(this);
- v->setSize(260, 180);
- v->createBuffer();
- v->setTitleBarColour(DrawStyle::DANGER);
- v->setTitleBarOn(1);
- v->setBorderOn(1);
- v->setTitleText(tr("Delete recording"));
- v->setMainText(tr("Are you sure you want to delete this recording?"));
- v->setDefault(VQuestion::NO);
- if (Video::getInstance()->getFormat() == Video::PAL)
- {
- v->setPosition(230, 160);
- }
- else
- {
- v->setPosition(220, 140);
- }
-
- v->draw();
- BoxStack::getInstance()->add(v);
- BoxStack::getInstance()->update(v);
- return 2;
- }
- }
+ if (selected == MOVE)
+ {
+ VRecMove* vrm = new VRecMove(recman);
+ vrm->setParent(this);
+ vrm->draw();
+ BoxStack::getInstance()->add(vrm);
+ BoxStack::getInstance()->update(vrm);
+ return 2;
+ }
- case Remote::BACK:
- {
- return 4;
- }
- }
- // stop command getting to any more views
- return 1;
+ if (selected == A_DELETE)
+ {
+ VQuestion* v = new VQuestion(this);
+ v->setSize(260, 180);
+ v->createBuffer();
+ v->setTitleBarColour(DrawStyle::DANGER);
+ v->setTitleBarOn(1);
+ v->setBorderOn(1);
+ v->setTitleText(tr("Delete recording"));
+ v->setMainText(tr("Are you sure you want to delete this recording?"));
+ v->setDefault(VQuestion::NO);
+ if (Video::getInstance()->getFormat() == Video::PAL)
+ {
+ v->setPosition(230, 160);
+ }
+ else
+ {
+ v->setPosition(220, 140);
+ }
+
+ v->draw();
+ BoxStack::getInstance()->add(v);
+ BoxStack::getInstance()->update(v);
+ return 2;
+ }
+ }
+ }
+ } else {
+ // Pass to tabbar
+ int retval = tabbar.handleCommand(command);
+ if (retval == 1)
+ {
+ BoxStack::getInstance()->update(this);
+ return 2;
+ }
+ else if (retval == 2)
+ {
+ // command was taken and actively ignored
+ if (command==Remote::LEFT || command==Remote::DF_LEFT
+ || command==Remote::RIGHT || command==Remote::DF_RIGHT)
+ {
+ buttons=true;
+ button[selected].setActive(1);
+ tabbar.activateFocus(false);
+ button[selected].draw();
+ tabbar.draw();
+ BoxStack::getInstance()->update(this);
+ }
+ return 2;
+ }
+ }
+
+
+ // stop command getting to any more views
+ return 1;
}
void VRecording::moveCursor(Direction direction)
#include "tbboxx.h"
#include "wbutton.h"
#include "wtextbox.h"
+#include "wtabbar.h"
class VRecordingList;
class RecMan;
RecMan* recman;
VRecordingList* vRecList;
Recording* rec;
-
- WTextbox summary;
+ WTabBar tabbar;
enum Action { PLAY=0, RESUME, MOVE, A_DELETE, last };
WButton button[last];
int selected;
Region buttonRegion;
+ bool buttons;
enum Direction { LEFT, RIGHT };
void moveCursor(Direction direction);
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "wmovieview.h"
+#include "i18n.h"
+#include <sstream>
+
+
+WMovieView::WMovieView(MovieInfo* movie):
+WTextbox(NULL)
+{
+ // portions from nopacity plugin by Louis Braun
+ if (movie)
+ {
+ std::stringstream info;
+ info << tr("TheMovieDB Information") << ":\n\n";
+ if (!movie->originalTitle.empty()){
+ info << tr("Original Title") << ": " << movie->originalTitle << "\n\n";
+ }
+ if (!movie->tagline.empty()){
+ info << tr("Tagline") << ": " << movie->tagline << "\n\n";
+ }
+ if (!movie->overview.empty()){
+ info << tr("Overview") << ": " << movie->overview << "\n\n";
+ }
+ const char* strAdult = (movie->adult)?(tr("yes")):(tr("no"));
+ info << tr("Adult") << ": " << strAdult << "\n\n";
+ if (!movie->collectionName.empty()){
+ info << tr("Collection") << ": " << movie->collectionName << "\n\n";
+ }
+ if (movie->budget > 0 ){
+ info << tr("Budget") << ": " << movie->budget << "$\n\n";
+ }
+ if (movie->revenue > 0 ){
+ info << tr("Revenue") << ": " << movie->revenue << "$\n\n";
+ }
+ if (!movie->genres.empty() ){
+ info << tr("Genre") << ": " << movie->genres << "\n\n";
+ }
+ if (!movie->homepage.empty()){
+ info << tr("Homepage") << ": " << movie->homepage << "\n\n";
+ }
+ if (!movie->releaseDate.empty()){
+ info << tr("Release Date") << ": " << movie->releaseDate << "\n\n";
+ }
+ if (movie->runtime > 0 ){
+ info << tr("Runtime") << ": " << movie->runtime << " " << tr("minutes") << "\n\n";
+ }
+ if (movie->popularity > 0 ){
+ info << tr("TheMovieDB Popularity") << ": " << movie->popularity << "\n\n";
+ }
+ if (movie->voteAverage > 0 ){
+ info << tr("TheMovieDB Vote Average") << ": " << movie->voteAverage << "\n\n";
+ }
+ setText(info.str().c_str());
+ } else {
+ setText("This is a bug!");
+ }
+
+}
+
+void WMovieView::draw()
+{
+ WTextbox::draw();
+
+
+}
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef WMOVIEVIEW_H
+#define WMOVIEVIEW_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "defines.h"
+#include "wtextbox.h"
+#include "movieinfo.h"
+
+class Colour;
+
+class WMovieView : public WTextbox
+{
+ public:
+ WMovieView(MovieInfo* movinfo);
+ void draw();
+
+
+ private:
+
+};
+
+#endif
WTextbox* tb = new WTextbox();
tb->setPosition(4, 4 + (numOptions * 30));
- tb->setSize(300, fontHeight);
+ tb->setSize(300, fontHeight + 6);
tb->setText(tr(option->displayText));
tb->setTextPos(0, 0);
add(tb);
--- /dev/null
+/*
+ Copyright 2005 Brian Walton (WTextBox)
+ Copyright 2014 Marten Richter (WPictureView)
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "wpictureview.h"
+
+#include "colour.h"
+#include "remote.h"
+#include "osd.h"
+#include "movieinfo.h"
+#include "seriesinfo.h"
+#include <math.h>
+
+WPictureView::WPictureView():
+foreColour(DrawStyle::LIGHTTEXT)
+{
+ cur_scroll_line=0;
+ rem_scroll_line=0;
+ const_height=0;
+}
+
+WPictureView::~WPictureView()
+{
+}
+
+
+
+void WPictureView::setForegroundColour(const DrawStyle& fcolour)
+{
+ foreColour = fcolour;
+}
+
+void WPictureView::draw()
+{
+ Boxx::draw();
+ int fontHeight = getFontHeight();
+ float ypos = cur_scroll_line * (fontHeight*8.f);
+ ypos = -ypos;
+ float height = 0;
+
+ drawClippingRectangle(1,1,area.w-1,area.h-1);
+
+ list<Picture>::iterator itty=pictures.begin();
+ while (itty!=pictures.end())
+ {
+ // We now calculate the pictures in one row
+ list<Picture*> cur_pict;
+ float cur_width=0;
+ float max_height=const_height;
+
+
+ while (itty != pictures.end())
+ {
+ if ((((*itty).w + cur_width+ 10.f) > area.w || const_height) && cur_pict.size() > 0) break;
+ cur_width += 10 + (*itty).w;
+ if (!const_height) max_height = max(max_height,(*itty).h);
+ cur_pict.push_back(&(*itty));
+ itty++;
+ }
+ // ok now we have a list of pictures, let's draw them
+ list<Picture*>::iterator citty=cur_pict.begin();
+ float xpos= (area.w - cur_width)*0.5f;
+ if (xpos < 0) xpos=0;
+ while (citty!=cur_pict.end())
+ {
+ if (!const_height) {
+ drawTVMedia((*citty)->media,
+ xpos, ypos + max_height /*- (*citty)->h*/,
+ (*citty)->w,
+ /*(*citty)->h*/0.f,BottomLeft);
+ } else {
+ if (!(*citty)->banner) {
+ drawTVMedia((*citty)->media,
+ xpos+area.w*0.5f, ypos,
+ 0.f,
+ const_height,TopMiddle);
+ } else {
+ drawTVMedia((*citty)->media,
+ xpos+area.w*0.5f, ypos,
+ area.w-2.f,
+ 0.f,TopMiddle);
+ }
+ }
+ xpos += (*citty)->w + 10.f;
+ citty++;
+ }
+ ypos += max_height;
+ height += max_height;
+ bool caption1=false;
+ bool caption2=false;
+
+ citty=cur_pict.begin();
+ xpos= (area.w - cur_width)*0.5f;
+ if (xpos < 0) xpos=0;
+ while (citty!=cur_pict.end())
+ {
+ if (!(*citty)->caption.empty())
+ {
+ drawTextCentre((*citty)->caption.c_str(), xpos + (*citty)->w*0.5f, ypos, foreColour);
+ caption1 = true;
+ }
+ if (!(*citty)->caption2.empty())
+ {
+ drawTextCentre((*citty)->caption2.c_str(), xpos + (*citty)->w*0.5f, ypos + fontHeight*1.f, foreColour);
+ caption2 = true;
+ }
+ xpos += (*citty)->w + 10.f;
+ citty++;
+ }
+ if (caption1) {
+ ypos +=fontHeight*1.f;
+ height += fontHeight*1.f;
+ }
+ if (caption2) {
+ ypos +=fontHeight*1.f;
+ height += fontHeight*1.f;
+ }
+ ypos +=fontHeight*1.f;
+ height += fontHeight*1.f;
+
+ }
+ rem_scroll_line = ceil((height - area.h -cur_scroll_line * fontHeight*8.f)/fontHeight/8.f);
+ // Log::getInstance()->log("WActorGallery", Log::DEBUG, "TVMedia rml %d",rem_scroll_line);
+ drawClippingRectangle(0,0,0,0);
+
+}
+
+void WPictureView::addPicture(TVMediaInfo& pict, float pwidth, float pheight , bool banner, std::string caption, std::string caption2)
+{
+ pictures.push_back(Picture(pict,pwidth,pheight, banner, caption,caption2));
+}
+
+int WPictureView::handleCommand(int command)
+{
+ switch(command)
+ {
+ case Remote::DF_UP:
+ case Remote::UP:
+ {
+ if (cur_scroll_line > 0)
+ {
+ cur_scroll_line--;
+ rem_scroll_line++;
+ return 1;
+ }
+ else
+ {
+ return 4; // Signal return control to parent
+ }
+ }
+ case Remote::DF_DOWN:
+ case Remote::DOWN:
+ {
+ if (rem_scroll_line > 0)
+ {
+ cur_scroll_line++;
+ rem_scroll_line--;
+ return 1;
+ } else {
+ return 4;
+ }
+ }
+ case Remote::LEFT:
+ case Remote::RIGHT:
+ case Remote::DF_LEFT:
+ case Remote::DF_RIGHT:
+ {
+ return 5;
+ }
+
+ }
+
+ return 0;
+}
+
+WActorGallery::WActorGallery(Actors& actors)
+{
+ Actors::iterator itty=actors.begin();
+ float pixelaspect=Osd::getInstance()->getPixelAspect();
+ while (itty!= actors.end())
+ {
+ float aspect=((float)(*itty).thumb.height)/((float)(*itty).thumb.width)/pixelaspect;
+ float width= 100;
+ float height= aspect*width;
+
+ //Log::getInstance()->log("WActorGallery", Log::DEBUG, "TVMedia %d %d %g", (*itty).thumb.width,(*itty).thumb.height,aspect);
+ addPicture((*itty).thumb.info, width, height, false,(*itty).name,"\""+(*itty).role+"\"");
+ itty++;
+ }
+}
+
+WArtworkGallery::WArtworkGallery(MovieInfo& movie)
+{
+ float pixelaspect=Osd::getInstance()->getPixelAspect();
+ addTVMedia(movie.fanart);
+ addTVMedia(movie.collectionFanart);
+ addTVMedia(movie.collectionPoster);
+ addTVMedia(movie.poster);
+ const_height=400;
+}
+
+WArtworkGallery::WArtworkGallery(SeriesInfo& series)
+{
+ addTVMedia(series.seasonposter);
+ addTVMedia(series.episode.image);
+
+ addTVMedias(series.banners, true);
+ addTVMedias(series.fanart);
+ addTVMedias(series.posters);
+ const_height=400;
+}
+
+void WArtworkGallery::addTVMedias(TVMedias& medias, bool banner)
+{
+ if (medias.size()) {
+ TVMedias::iterator titty=medias.begin();
+ while (titty!=medias.end())
+ {
+ addTVMedia(*titty, banner);
+ titty++;
+ }
+
+ }
+}
+
+void WArtworkGallery::addTVMedia(TVMedia& media, bool banner)
+{
+ if (media.width)
+ addPicture(media.info, media.width, media.height, banner);
+}
--- /dev/null
+/*
+ Copyright 2005 Brian Walton (WTextBox)
+ Copyright 2014 Marten Richter (WPictureView)
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef WPICTUREVIEW_H
+#define WPICTUREVIEW_H
+
+#include <stdio.h>
+#include <string>
+#include <list>
+
+#include "defines.h"
+#include "boxx.h"
+
+class Colour;
+
+class WPictureView : public Boxx
+{
+ public:
+ WPictureView();
+ virtual ~WPictureView();
+ void addPicture(TVMediaInfo& pict, float width, float height,bool banner=false, std::string caption ="", std::string caption2 ="");
+ void draw();
+ void setForegroundColour(const DrawStyle& fcolour);
+
+
+ // if added as a pane
+ int handleCommand(int command);
+
+ protected:
+ class Picture {
+ public:
+ Picture(TVMediaInfo tmedia,float width, float height, bool tbanner, std::string tcaption, std::string tcaption2){
+ media=tmedia; caption=tcaption;caption2=tcaption2;w=width; h=height; banner=tbanner;
+ }
+
+ TVMediaInfo media;
+ std::string caption;
+ std::string caption2;
+ float w;
+ float h;
+ bool banner;
+ };
+ list<Picture> pictures;
+
+ DrawStyle foreColour;
+ unsigned int cur_scroll_line;
+ unsigned int rem_scroll_line;
+ unsigned int const_height; // if set only one per line
+};
+
+class WActorGallery : public WPictureView
+{
+public:
+ WActorGallery(Actors& actors);
+
+};
+
+class WArtworkGallery : public WPictureView
+{
+public:
+ WArtworkGallery(MovieInfo& movie);
+ WArtworkGallery(SeriesInfo& series);
+protected:
+ void addTVMedias(TVMedias& medias, bool banner=false);
+ void addTVMedia(TVMedia& media, bool banner=false);
+
+};
+
+#endif
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "wseriesview.h"
+#include "i18n.h"
+#include <sstream>
+
+
+WSeriesView::WSeriesView(SeriesInfo* series):
+WTextbox(NULL)
+{
+ // portions from nopacity plugin by Louis Braun
+ if (series)
+ {
+ std::stringstream info;
+ info << tr("TheTVDB Information") << ":\n\n";
+
+ if (!series->episode.name.empty()) {
+ info << tr("Episode") << ": " << series->episode.name << " (" << tr("Season") << " " << series->episode.season << ", " << tr("Episode") << " " << series->episode.number << ")\n\n";
+ }
+ if (!series->episode.overview.empty()) {
+ info << tr("Episode Overview") << ": " << series->episode.overview << "\n\n";
+ }
+ if (!series->episode.firstAired.empty()) {
+ info << tr("First aired") << ": " << series->episode.firstAired << "\n\n";
+ }
+ if (!series->episode.guestStars.empty()) {
+ info << tr("Guest Stars") << ": " << series->episode.guestStars << "\n\n";
+ }
+ if (series->episode.rating > 0) {
+ info << tr("TheMovieDB Rating") << ": " << series->episode.rating << "\n\n";
+ }
+ if (!series->overview.empty()) {
+ info << tr("Series Overview") << ": " << series->overview << "\n\n";
+ }
+ if (!series->firstAired.empty()) {
+ info << tr("First aired") << ": " << series->firstAired << "\n\n";
+ }
+ if (!series->genre.empty()) {
+ info << tr("Genre") << ": " << series->genre << "\n\n";
+ }
+ if (!series->network.empty()) {
+ info << tr("Network") << ": " << series->network << "\n\n";
+ }
+ if (series->rating > 0) {
+ info << tr("TheMovieDB Rating") << ": " << series->rating << "\n\n";
+ }
+ if (!series->status.empty()) {
+ info << tr("Status") << ": " << series->status << "\n\n";
+ }
+ setText(info.str().c_str());
+ } else {
+ setText("This is a bug!");
+ }
+
+}
--- /dev/null
+/*
+ Copyright 2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef WSERIESVIEW_H
+#define WSERIESIEW_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "defines.h"
+#include "wtextbox.h"
+#include "seriesinfo.h"
+
+class Colour;
+
+class WSeriesView : public WTextbox
+{
+ public:
+ WSeriesView(SeriesInfo* seriesinfo);
+
+
+ private:
+
+};
+
+#endif
// 0 - not handled
// 1 - handled - stop command here
// 4 - handled - pane is returning control to here
+ // 5 - activate button bar and let button process the call, this for simple up and down scroll views
// FIXME standardise these
int paneRetCode = tabs[visiblePane].pane->handleCommand(command);
if (visiblePane != tabs.size() - 1) symbolRight.nextColour = DrawStyle::SELECTHIGHLIGHT;
draw();
return 1;
+ } else if (paneRetCode == 5)
+ {
+ buttonBarActive = true;
+ tabs[visiblePane].button->setActive(true);
+ if (visiblePane != 0) symbolLeft.nextColour = DrawStyle::SELECTHIGHLIGHT;
+ if (visiblePane != tabs.size() - 1) symbolRight.nextColour = DrawStyle::SELECTHIGHLIGHT;
+ draw();
+ // no return!
}
}
draw();
return 1;
}
+ case Remote::UP:
+ case Remote::DF_UP:
case Remote::DOWN:
case Remote::DF_DOWN:
{
return false;
}
+void WTabBar::activateFocus(bool active)
+{
+ if (active)
+ {
+ tabs[visiblePane].button->setActive(true);
+ buttonBarActive = true;
+
+ } else {
+ tabs[visiblePane].button->setActive(false);
+ buttonBarActive = false;
+
+ }
+}
+
int handleCommand(int command);
bool mouseMove(int x, int y) ;
bool mouseLBDOWN(int x, int y);
+ void activateFocus(bool active);
private:
bool left();
#include "wtextbox.h"
#include "colour.h"
+#include "remote.h"
WTextbox::WTextbox(const char* ttext):
foreColour(DrawStyle::LIGHTTEXT)
paraMode = true;
if (ttext) setText(ttext);
+
+ cur_scroll_line=0;
+ rem_scroll_line=0;
}
WTextbox::~WTextbox()
Boxx::draw();
if (text)
{
- if (paraMode) drawPara(text, textX, textY, foreColour);
+ if (paraMode) rem_scroll_line=drawPara(text, textX, textY, foreColour,cur_scroll_line);
else drawText(text, textX, textY, foreColour);
}
}
textX = x;
textY = y;
}
+
+int WTextbox::handleCommand(int command)
+{
+ switch(command)
+ {
+ case Remote::DF_UP:
+ case Remote::UP:
+ {
+ if (cur_scroll_line > 0)
+ {
+ cur_scroll_line--;
+ rem_scroll_line++;
+ return 1;
+ }
+ else
+ {
+ return 4; // Signal return control to parent
+ }
+ }
+ case Remote::DF_DOWN:
+ case Remote::DOWN:
+ {
+ if (rem_scroll_line > 0)
+ {
+ cur_scroll_line++;
+ rem_scroll_line--;
+ return 1;
+ } else {
+ return 4;
+ }
+ }
+ case Remote::LEFT:
+ case Remote::RIGHT:
+ case Remote::DF_LEFT:
+ case Remote::DF_RIGHT:
+ {
+ return 5;
+ }
+
+ }
+
+ return 0;
+}
void setTextPos(int x, int y); // optional
void setParaMode(bool mode);
+ // if added as a pane
+ int handleCommand(int command);
+
private:
char* text;
int textX;
int textY;
bool paraMode;
+ unsigned int cur_scroll_line;
+ unsigned int rem_scroll_line;
};
#endif