#include "viewelement.h" #include "../config.h" /****************************************************************** * cViewElement ******************************************************************/ cViewElement::cViewElement(void) { sdOsd = NULL; id = -1; dirty = true; init = true; drawn = false; scrollingStarted = false; blocked = false; detached = false; waitOnWakeup = true; startAnimation = true; globals = NULL; tokenContainer = NULL; attribs = new cViewElementAttribs((int)eViewElementAttribs::count); detacher = NULL; fader = NULL; shifter = NULL; } cViewElement::cViewElement(const cViewElement &other) { sdOsd = other.sdOsd; id = other.id; dirty = other.dirty; init = other.init; drawn = false; scrollingStarted = false; blocked = false; detached = false; waitOnWakeup = true; startAnimation = true; globals = other.globals; container.Set(other.container.X(), other.container.Y(), other.container.Width(), other.container.Height()); tokenContainer = NULL; attribs = new cViewElementAttribs(*other.attribs); for (cAreaNode *node = other.areaNodes.First(); node; node = other.areaNodes.Next(node)) { if (cArea *a = dynamic_cast(node)) { areaNodes.Add(new cArea(*a)); } else if (cAreaContainer *ac = dynamic_cast(node)) { areaNodes.Add(new cAreaContainer(*ac)); } } detacher = NULL; fader = NULL; shifter = NULL; } cViewElement::~cViewElement(void) { delete attribs; delete detacher; delete fader; delete shifter; delete tokenContainer; } /****************************************************************** * Public Functions ******************************************************************/ cViewElement *cViewElement::CreateViewElement(const char *name, const char *viewname) { cViewElement *e = NULL; //common view elements if (!strcmp(name, "background") && strcmp(viewname, "displayaudiotracks")) e = new cViewElement(); else if (!strcmp(name, "datetime")) e = new cVeDateTime(); else if (!strcmp(name, "time")) e = new cVeTime(); else if (!strcmp(name, "message")) e = new cVeMessage(); else if (!strcmp(name, "devices")) e = new cVeDevices(); else if (!strcmp(name, "currentweather")) e = new cVeCurrentWeather(); else if (!strcmp(name, "customtokens")) e = new cVeCustomTokens(); //displaychannel viewelements else if (!strcmp(name, "channelinfo")) e = new cVeDcChannelInfo(); else if (!strcmp(name, "channelgroup")) e = new cVeDcChannelGroup(); else if (!strcmp(name, "epginfo")) e = new cVeDcEpgInfo(); else if (!strcmp(name, "progressbar") && !strcmp(viewname, "displaychannel")) e = new cVeDcProgressBar(); else if (!strcmp(name, "statusinfo")) e = new cVeDcStatusInfo(); else if (!strcmp(name, "audioinfo")) e = new cVeDcAudioInfo(); else if (!strcmp(name, "screenresolution")) e = new cVeDcScreenResolution(); else if (!strcmp(name, "signalquality")) e = new cVeDcSignalQuality(); else if (!strcmp(name, "scrapercontent") && !strcmp(viewname, "displaychannel")) e = new cVeDcScraperContent(); else if (!strcmp(name, "ecminfo")) e = new cVeDcEcmInfo(); //displaymenu viewelements else if (!strcmp(name, "header") && strcmp(viewname, "displayaudiotracks")) e = new cVeDmHeader(); else if (!strcmp(name, "sortmode")) e = new cVeDmSortmode(); else if (!strcmp(name, "colorbuttons")) e = new cVeDmColorbuttons(); else if (!strcmp(name, "scrollbar")) e = new cVeDmScrollbar(); else if (!strcmp(name, "timers")) e = new cVeDmTimers(); else if (!strcmp(name, "currentschedule")) e = new cVeDmCurrentschedule(); else if (!strcmp(name, "discusage")) e = new cVeDmDiscusage(); else if (!strcmp(name, "systemload")) e = new cVeDmSystemload(); else if (!strcmp(name, "systemmemory")) e = new cVeDmSystemmemory(); else if (!strcmp(name, "temperatures")) e = new cVeDmTemperatures(); else if (!strcmp(name, "vdrstatistics")) e = new cVeDmVdrstatistics(); else if (!strcmp(name, "lastrecordings")) e = new cVeDmLastrecordings(); else if (!strcmp(name, "detailheaderepg")) e = new cVeDmDetailheaderEpg(); else if (!strcmp(name, "detailheaderrec")) e = new cVeDmDetailheaderRec(); else if (!strcmp(name, "detailheaderplugin")) e = new cVeDmDetailheaderPlugin(); else if (!strcmp(name, "tablabels")) e = new cVeDmTablabels(); //displayreplay viewelements else if (!strcmp(name, "backgroundmodeonly")) e = new cViewElement(); else if (!strcmp(name, "rectitle")) e = new cVeDrRecTitle(); else if (!strcmp(name, "recinfo")) e = new cVeDrRecInfo(); else if (!strcmp(name, "currenttime")) e = new cVeDrCurrentTime(); else if (!strcmp(name, "totaltime")) e = new cVeDrTotalTime(); else if (!strcmp(name, "endtime")) e = new cVeDrEndTime(); else if (!strcmp(name, "progressbar") && !strcmp(viewname, "displayreplay")) e = new cVeDrProgressBar(); else if (!strcmp(name, "cutmarks")) e = new cVeDrCutMarks(); else if (!strcmp(name, "controlicons")) e = new cVeDrControlIcons(); else if (!strcmp(name, "controliconsmodeonly")) e = new cVeDrControlIcons(); else if (!strcmp(name, "progressmodeonly")) e = new cVeDrProgressModeonly(); else if (!strcmp(name, "jump")) e = new cVeDrJump(); else if (!strcmp(name, "onpause")) e = new cVeDrOnPause(); else if (!strcmp(name, "onpausemodeonly")) e = new cVeDrOnPause(); else if (!strcmp(name, "scrapercontent") && !strcmp(viewname, "displayreplay")) e = new cVeDrScraperContent(); //displayvolume viewelements else if (!strcmp(name, "volume")) e = new cVeVolume(); //displayvolume viewelements else if (!strcmp(name, "background") && !strcmp(viewname, "displayaudiotracks")) e = new cVeDtBackground(); else if (!strcmp(name, "header") && !strcmp(viewname, "displayaudiotracks")) e = new cVeDtHeader(); //default else { dsyslog("skindesigner: unknown view element %s", name); e = new cViewElement(); } return e; } void cViewElement::SetGlobals(cGlobals *globals) { this->globals = globals; attribs->SetGlobals(globals); for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->SetGlobals(globals); } } void cViewElement::SetTokenContainer(void) { tokenContainer = new skindesignerapi::cTokenContainer(); InheritTokenContainer(); } bool cViewElement::Detached(void) { return detached; } void cViewElement::SetContainer(int x, int y, int width, int height) { container.SetX(x); container.SetY(y); container.SetWidth(width); container.SetHeight(height); } void cViewElement::SetAttributes(vector &attributes) { attribs->Set(attributes); } void cViewElement::AddArea(cAreaNode *area) { areaNodes.Add(area); } void cViewElement::SetAreaX(int x) { for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->SetX(x); } } void cViewElement::SetAreaY(int y) { for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->SetY(y); } } void cViewElement::SetAreaWidth(int width) { for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->SetWidth(width); } } void cViewElement::SetAreaHeight(int height) { for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->SetHeight(height); } } void cViewElement::SetPosition(int newX, int newY, int newWidth, int newHeight) { cRect newPos(newX, newY, newWidth, newHeight); for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->SetViewPort(newPos); } } void cViewElement::Cache(void) { attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); attribs->Cache(); for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); node->Cache(); } } bool cViewElement::Execute(void) { return attribs->DoExecute(); } void cViewElement::Clear(void) { tokenContainer->Clear(); for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { sdOsd->Lock(); node->Clear(); sdOsd->Unlock(); } dirty = false; drawn = false; scrollingStarted = false; } void cViewElement::Hide(void) { for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { sdOsd->Lock(); node->Hide(); sdOsd->Unlock(); } init = true; StopScrolling(); } void cViewElement::Show(void) { for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { sdOsd->Lock(); node->Show(); sdOsd->Unlock(); } } void cViewElement::WakeUp(void) { if (!detacher || !waitOnWakeup) { return; } detacher->WakeUp(); } void cViewElement::Close(void) { delete detacher; detacher = NULL; for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { sdOsd->Lock(); node->Close(); sdOsd->Unlock(); } StopScrolling(); dirty = true; init = true; startAnimation = true; drawn = false; scrollingStarted = false; blocked = false; } void cViewElement::Render(void) { if (!dirty || blocked) return; if (attribs->DoDebug()) Debug(); for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { //Check redraw of already scrolling list element if (drawn && scrollingStarted && node->Scrolling()) { if (DoScroll()) { //current list element continue; } else { //not current list element anymore scrollingStarted = false; } } sdOsd->Lock(); node->Clear(); sdOsd->Unlock(); if (!node->Execute()) continue; if (node->BackgroundArea() && drawn) continue; sdOsd->Lock(); node->Render(); sdOsd->Unlock(); if (DoScroll() && node->Scrolling()) { cArea *scrollArea = node->ScrollingArea(); if (scrollArea) { scrollingStarted = true; cAnimation *scroller = new cAnimation(scrollArea); scrollers.Add(scroller); scroller->Start(); } } } dirty = false; drawn = true; if (startAnimation) { startAnimation = false; StartAnimation(); } } void cViewElement::StopScrolling(bool deletePixmaps) { for (cAnimation *scroller = scrollers.First(); scroller; scroller = scrollers.Next(scroller)) { scroller->Stop(deletePixmaps); } scrollers.Clear(); } void cViewElement::ParseDetached(void) { Parse(true); } void cViewElement::RenderDetached(void) { blocked = false; Render(); } bool cViewElement::Shifting(void) { if (attribs->ShiftTime() >= 0) { return true; } return false; } bool cViewElement::Fading(void) { if (attribs->FadeTime() >= 0) { return true; } return false; } int cViewElement::FadeTime(void) { return attribs->FadeTime(); } int cViewElement::ShiftTime(void) { return attribs->ShiftTime(); } int cViewElement::ShiftMode(void) { return attribs->ShiftMode(); } void cViewElement::StartAnimation(void) { if (ShiftTime() > 0) { cRect shiftbox = CoveredArea(); cPoint ref = cPoint(shiftbox.X(), shiftbox.Y()); cPoint start = ShiftStart(shiftbox); SetPosition(start, ref); sdOsd->Flush(); delete shifter; shifter = new cAnimation((cShiftable*)this, start, ref, true); shifter->Start(); } else if (FadeTime() > 0) { SetTransparency(100); sdOsd->Flush(); delete fader; fader = new cAnimation((cFadable*)this, true); fader->Start(); } } void cViewElement::SetTransparency(int transparency, bool force) { for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { sdOsd->Lock(); node->SetTransparency(transparency); sdOsd->Unlock(); } } void cViewElement::SetPosition(cPoint &position, cPoint &reference, bool force) { for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { sdOsd->Lock(); node->SetPosition(position, reference); sdOsd->Unlock(); } } cRect cViewElement::CoveredArea(void) { cRect unionArea; for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { unionArea.Combine(node->CoveringArea()); } return unionArea; } void cViewElement::Flush(void) { sdOsd->Flush(); } bool cViewElement::Parse(bool forced) { if (blocked && !forced) { return false; } if (!Detached() || !init) { return true; } delete detacher; detacher = new cAnimation((cDetachable*)this, waitOnWakeup, startAnimation); detacher->Start(); startAnimation = false; init = false; blocked = true; return false; } cFunction *cViewElement::GetFunction(const char *name) { for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { if (cFunction *f = node->GetFunction(name)) return f; } return NULL; } void cViewElement::Debug(bool full) { esyslog("skindesigner: ---> viewElement %d", id); tokenContainer->Debug(); esyslog("skindesigner: container %d %d %dx%d", container.X(), container.Y(), container.Width(), container.Height()); attribs->Debug(); if (!full) return; for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->Debug(full); } } /****************************************************************** * protected Functions ******************************************************************/ void cViewElement::InheritTokenContainer(void) { tokenContainer->CreateContainers(); attribs->SetTokenContainer(tokenContainer); for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->SetTokenContainer(tokenContainer); } } void cViewElement::InheritTokenContainerDeep(void) { tokenContainer->CreateContainers(); attribs->SetTokenContainerDeep(tokenContainer); for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { node->SetTokenContainerDeep(tokenContainer); } } cPoint cViewElement::ShiftStart(cRect &shiftbox) { eShiftType type = (eShiftType)attribs->ShiftType(); cPoint start; if (type == eShiftType::none) { start = attribs->ShiftStartpoint(); } else if (type == eShiftType::left) { start.SetX(-shiftbox.Width()); start.SetY(shiftbox.Y()); } else if (type == eShiftType::right) { start.SetX(cOsd::OsdWidth()); start.SetY(shiftbox.Y()); } else if (type == eShiftType::top) { start.SetX(shiftbox.X()); start.SetY(-shiftbox.Height()); } else if (type == eShiftType::bottom) { start.SetX(shiftbox.X()); start.SetY(cOsd::OsdHeight()); } return start; }