redesigned animations

This commit is contained in:
louis
2016-07-22 15:21:09 +02:00
parent 4f3c24df7b
commit a79af20c34
70 changed files with 1484 additions and 827 deletions

View File

@@ -1,220 +1,40 @@
#include "../config.h"
#include "animation.h"
#include <math.h>
/******************************************************************
* cAnimation
* cDetacher
******************************************************************/
cAnimation::cAnimation(cScrollable *scrollable) : cThread("scroller") {
this->scrollable = scrollable;
this->detachable = NULL;
this->fadable = NULL;
this->shiftable = NULL;
this->blinkable = NULL;
waitOnWakeup = false;
keepSleeping = false;
doAnimation = true;
modeIn = false;
blinkFunc = -1;
}
cAnimation::cAnimation(cDetachable *detachable, bool wait, bool animation) : cThread("detached") {
this->scrollable = NULL;
cDetacher::cDetacher(cDetachable *detachable, bool wait, bool animation) : cThread("detacher thread") {
this->detachable = detachable;
this->fadable = NULL;
this->shiftable = NULL;
this->blinkable = NULL;
waitOnWakeup = wait;
keepSleeping = false;
doAnimation = animation;
modeIn = false;
blinkFunc = -1;
}
cAnimation::cAnimation(cFadable *fadable, bool fadein) : cThread("fadable") {
this->scrollable = NULL;
this->detachable = NULL;
this->fadable = fadable;
this->shiftable = NULL;
this->blinkable = NULL;
waitOnWakeup = false;
keepSleeping = false;
doAnimation = true;
modeIn = fadein;
blinkFunc = -1;
}
cAnimation::cAnimation(cShiftable *shiftable, cPoint &start, cPoint &end, bool shiftin) : cThread("shiftable") {
this->scrollable = NULL;
this->detachable = NULL;
this->fadable = NULL;
this->shiftable = shiftable;
this->blinkable = NULL;
waitOnWakeup = false;
keepSleeping = false;
doAnimation = true;
modeIn = shiftin;
shiftstart = start;
shiftend = end;
blinkFunc = -1;
}
cAnimation::cAnimation(cBlinkable *blinkable, int func) : cThread("blinking") {
this->scrollable = NULL;
this->detachable = NULL;
this->fadable = NULL;
this->shiftable = NULL;
this->blinkable = blinkable;
waitOnWakeup = false;
keepSleeping = false;
doAnimation = true;
modeIn = false;
blinkFunc = func;
}
cAnimation::~cAnimation(void) {
cDetacher::~cDetacher(void) {
sleepWait.Signal();
Cancel(2);
}
void cAnimation::WakeUp(void) {
void cDetacher::WakeUp(void) {
sleepWait.Signal();
}
void cAnimation::ResetSleep(void) {
void cDetacher::ResetSleep(void) {
keepSleeping = true;
sleepWait.Signal();
}
void cAnimation::Stop(bool deletePixmaps) {
void cDetacher::Stop(bool deletePixmaps) {
sleepWait.Signal();
Cancel(2);
if (scrollable && deletePixmaps)
scrollable->StopScrolling();
}
void cAnimation::Action(void) {
if (scrollable) {
Scroll();
scrollable->UnregisterAnimation();
} else if (detachable) {
Detach();
} else if (fadable) {
Fade();
fadable->UnregisterAnimation();
} else if (shiftable) {
Shift();
shiftable->UnregisterAnimation();
} else if (blinkable) {
blinkable->RegisterAnimation();
Blink();
blinkable->UnregisterAnimation();
}
}
void cAnimation::Sleep(int duration) {
//sleep should wake up itself, so no infinit wait allowed
if (duration <= 0)
void cDetacher::Action(void) {
if (!detachable) {
return;
do {
keepSleeping = false;
sleepWait.Wait(duration);
} while (keepSleeping);
}
void cAnimation::Wait(void) {
//wait has to be waked up from outside
sleepWait.Wait(0);
}
void cAnimation::Scroll(void) {
int delay = scrollable->ScrollDelay();
Sleep(delay);
scrollable->RegisterAnimation();
if (!Running()) return;
eOrientation orientation = scrollable->ScrollOrientation();
int scrollTotal = 0;
if (orientation == eOrientation::horizontal) {
scrollTotal = scrollable->ScrollWidth();
} else if (orientation == eOrientation::vertical) {
scrollTotal = scrollable->ScrollHeight();
}
eScrollMode mode = scrollable->ScrollMode();
bool carriageReturn = (mode == eScrollMode::carriagereturn) ? true : false;
eScrollSpeed speed = scrollable->ScrollSpeed();
int frameTime = 30;
if (speed == eScrollSpeed::slow)
frameTime = 50;
else if (speed == eScrollSpeed::medium)
frameTime = 30;
else if (speed == eScrollSpeed::fast)
frameTime = 15;
if (!Running()) return;
scrollable->StartScrolling();
int drawPortX = 0;
int drawPortY = 0;
int scrollDelta = 1;
bool doSleep = false;
while (Running()) {
if (doSleep) {
Sleep(delay);
doSleep = false;
}
if (!Running()) return;
uint64_t now = cTimeMs::Now();
cPoint drawPortPoint(0,0);
if (orientation == eOrientation::horizontal) {
drawPortX -= scrollDelta;
if (abs(drawPortX) > scrollTotal) {
Sleep(delay);
if (carriageReturn) {
drawPortX = 0;
doSleep = true;
} else {
scrollDelta *= -1;
drawPortX -= scrollDelta;
}
}
drawPortPoint.SetX(drawPortX);
} else if (orientation == eOrientation::vertical) {
drawPortY -= scrollDelta;
if (abs(drawPortY) > scrollTotal) {
Sleep(delay);
drawPortY = 0;
doSleep = true;
}
drawPortPoint.SetY(drawPortY);
}
if (!Running()) return;
scrollable->SetDrawPort(drawPortPoint);
if (!Running()) return;
scrollable->Flush(true);
if (orientation == eOrientation::horizontal && !carriageReturn && (drawPortX == 0)) {
scrollDelta *= -1;
doSleep = true;
}
int delta = cTimeMs::Now() - now;
if (delta < frameTime)
Sleep(frameTime - delta);
}
}
void cAnimation::Detach(void) {
if (waitOnWakeup) {
Wait();
int delay = 50 + detachable->Delay();
@@ -224,155 +44,625 @@ void cAnimation::Detach(void) {
if (delay > 0)
Sleep(delay);
}
//if (!Running()) return;
detachable->ParseDetached();
//if (!Running()) return;
detachable->RenderDetached();
//if (!Running()) return;
if (!doAnimation)
detachable->Flush(false);
detachable->Flush();
if (!Running()) return;
if (doAnimation) {
detachable->StartAnimation();
}
}
void cAnimation::Fade(void) {
int fadetime = fadable->FadeTime();
int frametime = 1000 / FPS;
int step = 100.0f / ((double)fadetime / (double)frametime);
uint64_t start = cTimeMs::Now();
int transparency = 0;
if (modeIn) {
transparency = 100 - step;
} else {
transparency = step;
}
//wait configured delay if not already done by detacher
if (!fadable->Detached()) {
int delay = fadable->Delay();
if (delay > 0)
Sleep(delay);
}
fadable->RegisterAnimation();
while (Running() || !modeIn) {
uint64_t now = cTimeMs::Now();
if (Running() || !modeIn)
fadable->SetTransparency(transparency, !modeIn);
if (Running() || !modeIn)
fadable->Flush(true);
int delta = cTimeMs::Now() - now;
if ((Running() || !modeIn) && (delta < frametime)) {
Sleep(frametime - delta);
}
if ((int)(now - start) > fadetime) {
if ((Running() && modeIn) && transparency > 0) {
fadable->SetTransparency(0);
fadable->Flush(true);
} else if (!modeIn && transparency < 100) {
fadable->SetTransparency(100, true);
fadable->Flush(true);
}
break;
}
if (modeIn) {
transparency -= step;
if (transparency < 0)
transparency = 0;
} else {
transparency += step;
if (transparency > 100)
transparency = 100;
}
}
}
void cAnimation::Shift(void) {
int shifttime = shiftable->ShiftTime();
eShiftMode mode = (eShiftMode)shiftable->ShiftMode();
//in shiftmode slowedDown shifting is done starting with slowratio % faster
//at start. Then speed reduces linear to (100 - slowratio)% at end
//for me 60 is a nice value :-)
int slowRatio = 60;
int frametime = 1000 / FPS;
int steps = (double)shifttime / (double)frametime;
if (steps < 2)
void cDetacher::Sleep(int duration) {
if (duration <= 0)
return;
int stepXLinear = 0;
int stepYLinear = 0;
if (shiftstart.X() == shiftend.X()) {
stepYLinear = (shiftend.Y() - shiftstart.Y()) / steps;
} else if (shiftstart.Y() == shiftend.Y()) {
stepXLinear = (shiftend.X() - shiftstart.X()) / steps;
} else {
stepXLinear = (shiftend.X() - shiftstart.X()) / steps;
stepYLinear = (shiftend.Y() - shiftstart.Y()) / steps;
}
int stepX = stepXLinear;
int stepY = stepYLinear;
do {
keepSleeping = false;
sleepWait.Wait(duration);
} while (keepSleeping);
}
cPoint pos;
if (modeIn)
pos = shiftstart;
void cDetacher::Wait(void) {
//wait has to be waked up from outside
sleepWait.Wait(0);
}
/******************************************************************
* cAnimaton
******************************************************************/
cAnimation::cAnimation(void) {
started = 0;
finished = false;
persistent = false;
frametime = 1000 / config.FPS;
}
cAnimation::~cAnimation(void) {
}
/******************************************************************
* cScroller
******************************************************************/
cScroller::cScroller(cScrollable *scrollable) {
this->scrollable = scrollable;
paused = true;
pauseTime = 0;
scrollingStarted = false;
secondDelay = false;
delScrollPix = true;
Init();
}
cScroller::~cScroller(void) {
}
void cScroller::Init(void) {
delay = scrollable->ScrollDelay();
orientation = scrollable->ScrollOrientation();
if (orientation == eOrientation::horizontal) {
scrollLength = scrollable->ScrollWidth();
} else if (orientation == eOrientation::vertical) {
scrollLength = scrollable->ScrollHeight();
}
eScrollMode mode = scrollable->ScrollMode();
carriageReturn = (mode == eScrollMode::carriagereturn) ? true : false;
drawPortX = 0.0f;
drawPortY = 0.0f;
eScrollSpeed speed = scrollable->ScrollSpeed();
if (speed == eScrollSpeed::slow)
scrollDelta = 0.5f;
else if (speed == eScrollSpeed::fast)
scrollDelta = 2.0f;
else
pos = shiftend;
scrollDelta = 1.0f;
}
//wait configured delay if not already done by detacher
if (!shiftable->Detached()) {
int delay = shiftable->Delay();
if (delay > 0)
Sleep(delay);
void cScroller::Reactivate(void) {}
void cScroller::SetInitial(void) {}
bool cScroller::Pause(void) {
if (!paused)
return false;
if ((pauseTime + frametime) > delay) {
paused = false;
pauseTime = 0;
return false;
}
shiftable->RegisterAnimation();
shiftable->SetStartShifting();
uint64_t start = cTimeMs::Now();
bool finished = false;
while (Running() || !modeIn) {
uint64_t now = cTimeMs::Now();
if (Running() || !modeIn)
shiftable->SetPosition(pos, shiftend);
if (Running() || !modeIn)
shiftable->Flush(true);
int delta = cTimeMs::Now() - now;
if ((Running() || !modeIn) && (delta < frametime)) {
cCondWait::SleepMs(frametime - delta);
pauseTime += frametime;
return true;
}
bool cScroller::Overflow(void) {
if (orientation == eOrientation::horizontal) {
if (!carriageReturn && (drawPortX >= 1)) {
drawPortX = 0;
scrollDelta *= -1;
paused = true;
return true;
}
if ((int)(now - start) > shifttime) {
finished = true;
if ((Running() && modeIn) && pos != shiftend) {
shiftable->SetPosition(shiftend, shiftend);
shiftable->Flush(true);
if (carriageReturn && (drawPortX >= 0) && secondDelay) {
cPoint drawPortPoint(drawPortX,0);
scrollable->SetDrawPort(drawPortPoint);
drawPortX = -1;
paused = true;
secondDelay = false;
return true;
}
if (abs(drawPortX) < scrollLength)
return false;
if (carriageReturn) {
drawPortX = 0;
secondDelay = true;
} else {
scrollDelta *= -1;
drawPortX -= scrollDelta;
}
} else if (orientation == eOrientation::vertical) {
if ((drawPortY >= 0) && secondDelay) {
cPoint drawPortPoint(0, drawPortY);
scrollable->SetDrawPort(drawPortPoint);
drawPortY = -1;
paused = true;
secondDelay = false;
return true;
}
if (abs(drawPortY) < scrollLength)
return false;
secondDelay = true;
drawPortY = 0;
}
paused = true;
return true;
}
void cScroller::SetFinished(void) {
finished = true;
if (delScrollPix) {
scrollable->StopScrolling();
}
}
bool cScroller::Tick(void) {
if (finished) {
return false;
}
if (Pause())
return true;
if (!scrollingStarted) {
scrollable->StartScrolling();
scrollingStarted = true;
}
if (Overflow())
return true;
cPoint drawPortPoint(0,0);
if (orientation == eOrientation::horizontal) {
drawPortX -= scrollDelta;
drawPortPoint.SetX(drawPortX);
} else if (orientation == eOrientation::vertical) {
drawPortY -= scrollDelta;
drawPortPoint.SetY(drawPortY);
}
scrollable->SetDrawPort(drawPortPoint);
return true;
};
/******************************************************************
* cFader
******************************************************************/
cFader::cFader(cFadable *fadable) {
this->fadable = fadable;
fadein = true;
fadetime = fadable->FadeTime();
step = 100.0f / ((double)fadetime / (double)frametime);
transparency = 100;
hideWhenFinished = false;
}
cFader::~cFader(void) {
}
void cFader::Reactivate(void) {
started = 0;
finished = false;
fadein = false;
}
void cFader::SetInitial(void) {
fadable->SetTransparency(transparency);
}
void cFader::SetFadeOut(void) {
fadein = false;
transparency = 0;
}
void cFader::SetFinished(void) {
finished = true;
if (hideWhenFinished)
fadable->SetTransparency(100);
}
bool cFader::Tick(void) {
if (finished) {
if (fadein)
fadable->SetTransparency(0);
else
fadable->SetTransparency(100);
return false;
}
if (!started) {
started = cTimeMs::Now();
}
if ((int)(cTimeMs::Now() - started) > fadetime) {
if (fadein)
fadable->SetTransparency(0);
else
fadable->SetTransparency(100);
finished = true;
return false;
}
fadable->SetTransparency(transparency);
if (fadein) {
transparency -= step;
} else {
transparency += step;
}
return true;
};
/******************************************************************
* cShifter
******************************************************************/
cShifter::cShifter(cShiftable *shiftable) {
this->shiftable = shiftable;
step = 0;
shiftin = true;
shifttime = 0;
x = 0.0f;
y = 0.0f;
stepXLinear = 0;
stepYLinear = 0;
stepsFast = 0;
stepXFast = 0;
stepXSlow = 0;
stepYFast = 0;
stepYSlow = 0;
Init();
}
cShifter::~cShifter(void) {
}
void cShifter::Init(void) {
shifttime = shiftable->ShiftTime();
mode = (eShiftMode)shiftable->ShiftMode();
shiftable->ShiftPositions(&start, &end);
int steps = (double)shifttime / (double)frametime;
float percentFast = 33.3f;
float distanceFast = 85.0f;
stepsFast = (float)steps * percentFast / 100.0f;
if (start.X() == end.X()) {
stepYLinear = (float)(end.Y() - start.Y()) / (float)steps;
stepYFast = (float)(end.Y() - start.Y()) * distanceFast / 100.0f / (float)stepsFast;
stepYSlow = (float)(end.Y() - start.Y()) * (100.0f - distanceFast) / 100.0f / (float)(steps-stepsFast);
} else if (start.Y() == end.Y()) {
stepXLinear = (end.X() - start.X()) / steps;
stepXFast = (float)(end.X() - start.X()) * distanceFast / 100.0f / (float)stepsFast;
stepXSlow = (float)(end.X() - start.X()) * (100.0f - distanceFast) / 100.0f / (float)(steps-stepsFast);
} else {
stepXLinear = (end.X() - start.X()) / steps;
stepXFast = (float)(end.X() - start.X()) * distanceFast / 100.0f / (float)stepsFast;
stepXSlow = (float)(end.X() - start.X()) * (100.0f - distanceFast) / 100.0f / (float)(steps-stepsFast);
stepYLinear = (end.Y() - start.Y()) / steps;
stepYFast = (float)(end.Y() - start.Y()) * distanceFast / 100.0f / (float)stepsFast;
stepYSlow = (float)(end.Y() - start.Y()) * (100.0f - distanceFast) / 100.0f / (float)(steps-stepsFast);
}
x = start.X();
y = start.Y();
}
void cShifter::Reactivate(void) {
started = 0;
finished = false;
shiftin = false;
step = 0;
}
void cShifter::SetInitial(void) {
cPoint pos(x, y);
shiftable->SetPosition(pos, end);
}
void cShifter::NextPosition(void) {
if (mode == eShiftMode::linear) {
if (shiftin) {
x += stepXLinear;
y += stepYLinear;
} else {
x -= stepXLinear;
y -= stepYLinear;
}
} else if (mode == eShiftMode::slowedDown) {
if (shiftin) {
if (step <= stepsFast) {
x += stepXFast;
y += stepYFast;
} else {
x += stepXSlow;
y += stepYSlow;
}
} else {
if (step <= stepsFast) {
x -= stepXFast;
y -= stepYFast;
} else {
x -= stepXSlow;
y -= stepYSlow;
}
}
}
}
bool cShifter::Tick(void) {
if (finished)
return false;
if (!started) {
started = cTimeMs::Now();
}
if ((int)(cTimeMs::Now() - started) > shifttime) {
if (shiftin)
shiftable->SetPosition(end, end);
else
shiftable->SetPosition(start, end);
finished = true;
return false;
}
cPoint pos(x, y);
shiftable->SetPosition(pos, end);
step++;
NextPosition();
return true;
};
/******************************************************************
* cListShifter
******************************************************************/
cListShifter::cListShifter(cListShiftable *shiftable) {
this->shiftable = shiftable;
shifttime = shiftable->ListShiftTime();
distance = shiftable->ShiftDistance();
orientation = shiftable->ShiftOrientation();
int steps = (double)shifttime / (double)frametime;
step = distance / steps;
shiftin = true;
fromtop = true;
}
cListShifter::~cListShifter(void) {
}
void cListShifter::Reactivate(void) {}
void cListShifter::SetInitial(void) {
if (shiftin) {
if (orientation == eOrientation::horizontal) {
if (fromtop) {
pos.SetX(-1 * distance);
pos.SetY(0);
} else {
pos.SetX(distance);
pos.SetY(0);
}
} else {
if (fromtop) {
pos.SetX(0);
pos.SetY(-1 * distance);
} else {
pos.SetX(0);
pos.SetY(distance);
}
}
}
shiftable->SetIndicatorPosition(pos);
}
void cListShifter::NextPosition(void) {
int x = pos.X();
int y = pos.Y();
if (orientation == eOrientation::horizontal) {
if (fromtop) {
pos.SetX(x+step);
} else {
pos.SetX(x-step);
}
} else {
if (fromtop) {
pos.SetY(y+step);
} else {
pos.SetY(y-step);
}
}
}
void cListShifter::EndPosition(void) {
if (shiftin) {
pos.SetX(0);
pos.SetY(0);
} else {
if (orientation == eOrientation::horizontal) {
pos.SetX(distance);
} else {
pos.SetY(distance);
}
}
shiftable->SetIndicatorPosition(pos);
}
bool cListShifter::Tick(void) {
if (finished) {
EndPosition();
return false;
}
if (!started) {
started = cTimeMs::Now();
}
if ((int)(cTimeMs::Now() - started) > shifttime) {
EndPosition();
finished = true;
return false;
}
shiftable->SetIndicatorPosition(pos);
NextPosition();
return true;
};
/******************************************************************
* cBlinker
******************************************************************/
cBlinker::cBlinker(cBlinkable *blinkable, int blinkFunc) {
this->blinkable = blinkable;
this->blinkFunc = blinkFunc;
freq = blinkable->BlinkFreq(blinkFunc);
blinkOn = false;
paused = true;
pauseTime = 0;
}
cBlinker::~cBlinker(void) {
}
void cBlinker::Reactivate(void) {}
void cBlinker::SetInitial(void) {}
bool cBlinker::Pause(void) {
if (!paused)
return false;
if ((pauseTime + frametime) > freq) {
paused = false;
pauseTime = 0;
return false;
}
pauseTime += frametime;
return true;
}
bool cBlinker::Tick(void) {
if (finished)
return false;
if (Pause())
return true;
blinkable->DoBlink(blinkFunc, blinkOn);
blinkOn = !blinkOn;
paused = true;
pauseTime = 0;
return true;
};
/******************************************************************
* cAnimator
******************************************************************/
cAnimator::cAnimator(cSdOsd *osd) : cThread("animator thread") {
this->osd = osd;
timeneeded = 0;
timeslice = 1000 / config.FPS;
}
cAnimator::~cAnimator(void) {
Stop();
}
void cAnimator::Sleep(uint64_t start) {
timeneeded = cTimeMs::Now() - start;
int sleepTime = (timeslice - timeneeded) > 0 ? timeslice - timeneeded : 0;
if (sleepTime)
sleepWait.Wait(sleepTime);
}
void cAnimator::DoTick(bool &animActive) {
animLock.Lock();
for (cAnimation *animation = animations.First(); animation; animation = animations.Next(animation)) {
if (Running()) {
bool currentAnimActive = animation->Tick();
animActive = animActive || currentAnimActive;
}
}
animLock.Unlock();
}
/*****************************************************************************************
* Cleanup Anims
* removes finished anims
* remembers persistent anims
*****************************************************************************************/
void cAnimator::CleanupAnims(void) {
bool found;
animLock.Lock();
do {
found = false;
for (cAnimation *animation = animations.First(); animation; animation = animations.Next(animation)) {
if (!animation->Finished())
continue;
if (animation->Persistent()) {
animations.Del(animation, false);
animationsPersistent.Add(animation);
} else {
animations.Del(animation);
}
found = true;
break;
}
if (mode == eShiftMode::slowedDown) {
double t = (double)(now - start) / (double)shifttime;
double factor = 1.0f + (double)slowRatio / 100.0f - 2.0f * ((double)slowRatio / 100.0f) * t;
stepX = stepXLinear * factor;
stepY = stepYLinear * factor;
}
if (modeIn) {
pos.Set(pos.X() + stepX, pos.Y() + stepY);
} else {
pos.Set(pos.X() - stepX, pos.Y() - stepY);
}
}
if (!finished) {
shiftable->SetPosition(shiftend, shiftend);
}
shiftable->SetEndShifting();
} while (found);
animLock.Unlock();
}
void cAnimation::Blink(void) {
int freq = blinkable->BlinkFreq(blinkFunc);
bool blinkOn = false;
while (Running()) {
Sleep(freq);
if (Running())
blinkable->DoBlink(blinkFunc, blinkOn);
if (Running())
blinkable->Flush(true);
blinkOn = !blinkOn;
/*****************************************************************************************
* Main Loop
*****************************************************************************************/
void cAnimator::Action(void) {
while(Running()) {
bool animActive = false;
uint64_t start = cTimeMs::Now();
DoTick(animActive); if (!Running()) break;
osd->Flush(); if (!Running()) break;
CleanupAnims(); if (!Running()) break;
if (!animActive) {
pauseWait.Wait();
} else {
Sleep(start);
}
}
}
/*****************************************************************************************
* Add Animation
* if startAnim is set to true, main loop gets waked up
*****************************************************************************************/
void cAnimator::AddAnimation(cAnimation *animation, bool startAnim) {
animation->SetInitial();
animLock.Lock();
animations.Ins(animation);
animLock.Unlock();
if (startAnim)
pauseWait.Signal();
}
/*****************************************************************************************
* Remove Animation
* animation will be set to finished and removed later by Cleanup()
*****************************************************************************************/
void cAnimator::RemoveAnimation(cAnimation *remove) {
animLock.Lock();
for (cAnimation *animation = animations.First(); animation; animation = animations.Next(animation)) {
if (animation == remove) {
animation->SetFinished();
break;
}
}
animLock.Unlock();
}
/*****************************************************************************************
* Finish Main Loop
*****************************************************************************************/
void cAnimator::Stop(void) {
if (!Running())
return;
Cancel(-1);
pauseWait.Signal();
sleepWait.Signal();
Cancel(2);
}
/*****************************************************************************************
* shift or fade out persistent animations
*****************************************************************************************/
void cAnimator::Finish(void) {
bool animActive = true;
bool reactivate = true;
while(animActive) {
animActive = false;
uint64_t start = cTimeMs::Now();
animLock.Lock();
for (cAnimation *animation = animationsPersistent.First(); animation; animation = animationsPersistent.Next(animation)) {
if (reactivate)
animation->Reactivate();
bool currentAnimActive = animation->Tick();
animActive = animActive || currentAnimActive;
}
animLock.Unlock();
reactivate = false;
osd->Flush();
if (!animActive)
break;
Sleep(start);
}
}

View File

@@ -4,11 +4,64 @@
#include <vdr/skins.h>
#include <vdr/thread.h>
#include "definitions.h"
#define FPS 50
#include "osdwrapper.h"
/******************************************************************
* cScrollable
* Detaching
******************************************************************/
class cDetachable {
protected:
cDetachable(void) {};
~cDetachable(void) {};
public:
virtual int Delay(void) = 0;
virtual void StartAnimation(void) = 0;
virtual void ParseDetached(void) = 0;
virtual void RenderDetached(void) = 0;
virtual void Flush(void) = 0;
};
class cDetacher : public cThread, public cListObject {
private:
cCondWait sleepWait;
cDetachable *detachable;
bool waitOnWakeup;
bool keepSleeping;
bool doAnimation;
void Sleep(int duration);
void Wait(void);
virtual void Action(void);
public:
cDetacher(cDetachable *detachable, bool wait, bool animation);
~cDetacher(void);
void WakeUp(void);
void ResetSleep(void);
void Stop(bool deletePixmaps);
};
/******************************************************************
* cAnimation
******************************************************************/
class cAnimation : public cListObject {
protected:
uint64_t started;
bool finished;
bool persistent;
int frametime;
public:
cAnimation(void);
virtual ~cAnimation(void);
virtual void SetInitial(void) = 0;
virtual void Reactivate(void) = 0;
virtual bool Tick(void) = 0;
bool Finished(void) { return finished; };
virtual void SetFinished(void) { finished = true; };
void SetPersistent(void) { persistent = true; };
bool Persistent(void) { return persistent; };
};
/******************************************************************
* Scrolling
******************************************************************/
class cScrollable {
protected:
@@ -24,67 +77,140 @@ public:
virtual void StartScrolling(void) = 0;
virtual void StopScrolling(void) = 0;
virtual void SetDrawPort(cPoint &point) = 0;
virtual void RegisterAnimation(void) = 0;
virtual void UnregisterAnimation(void) = 0;
virtual void Flush(bool animFlush) = 0;
};
/******************************************************************
* cDetachable
******************************************************************/
class cDetachable {
protected:
cDetachable(void) {};
~cDetachable(void) {};
class cScroller : public cAnimation {
private:
cScrollable *scrollable;
int delay;
bool paused;
int pauseTime;
bool scrollingStarted;
bool secondDelay;
eOrientation orientation;
int scrollLength;
bool carriageReturn;
float drawPortX;
float drawPortY;
float scrollDelta;
bool delScrollPix;
void Init(void);
bool Pause(void);
bool Overflow(void);
public:
virtual int Delay(void) = 0;
virtual void ParseDetached(void) = 0;
virtual void RenderDetached(void) = 0;
virtual void StartAnimation(void) = 0;
virtual void RegisterAnimation(void) = 0;
virtual void UnregisterAnimation(void) = 0;
virtual void Flush(bool animFlush) = 0;
cScroller(cScrollable *scrollable);
~cScroller(void);
void SetInitial(void);
void Reactivate(void);
void SetFinished(void);
void UnsetDelScrollPix(void) { delScrollPix = false; };
bool Tick(void);
};
/******************************************************************
* cFadable
* Fading
******************************************************************/
class cFadable {
protected:
cFadable(void) {};
~cFadable(void) {};
public:
virtual bool Detached(void) = 0;
virtual int Delay(void) = 0;
virtual int FadeTime(void) = 0;
virtual void SetTransparency(int transparency, bool force = false) = 0;
virtual void RegisterAnimation(void) = 0;
virtual void UnregisterAnimation(void) = 0;
virtual void Flush(bool animFlush) = 0;
};
class cFader : public cAnimation {
private:
cFadable *fadable;
bool fadein;
int fadetime;
int step;
int transparency;
bool hideWhenFinished;
public:
cFader(cFadable *fadable);
~cFader(void);
void SetInitial(void);
void Reactivate(void);
void SetFadeOut(void);
void SetFinished(void);
void SetHideWhenFinished(void) { hideWhenFinished = true; };
bool Tick(void);
};
/******************************************************************
* cShiftable
* Shifting
******************************************************************/
class cShiftable {
protected:
cShiftable(void) {};
~cShiftable(void) {};
public:
virtual bool Detached(void) = 0;
virtual int Delay(void) = 0;
virtual int ShiftTime(void) = 0;
virtual int ShiftMode(void) = 0;
virtual void ShiftPositions(cPoint *start, cPoint *end) = 0;
virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false) = 0;
virtual void SetStartShifting(void) = 0;
virtual void SetEndShifting(void) = 0;
virtual void RegisterAnimation(void) = 0;
virtual void UnregisterAnimation(void) = 0;
virtual void Flush(bool animFlush) = 0;
};
class cListShiftable {
protected:
cListShiftable(void) {};
~cListShiftable(void) {};
public:
virtual int ListShiftTime(void) = 0;
virtual int ShiftDistance(void) = 0;
virtual eOrientation ShiftOrientation(void) = 0;
virtual void SetIndicatorPosition(cPoint &position) = 0;
};
class cShifter : public cAnimation {
private:
cShiftable *shiftable;
bool shiftin;
cPoint start, end;
int shifttime;
eShiftMode mode;
int step;
float stepXLinear, stepYLinear;
int stepsFast;
float stepXFast, stepXSlow;
float stepYFast, stepYSlow;
float x, y;
void Init(void);
void NextPosition(void);
public:
cShifter(cShiftable *shiftable);
~cShifter(void);
void SetInitial(void);
void Reactivate(void);
bool Tick(void);
};
class cListShifter : public cAnimation {
private:
cListShiftable *shiftable;
bool shiftin;
bool fromtop;
int distance;
eOrientation orientation;
int shifttime;
int step;
cPoint pos;
void NextPosition(void);
void EndPosition(void);
public:
cListShifter(cListShiftable *shiftable);
~cListShifter(void);
void SetInitial(void);
void Reactivate(void);
void SetShiftOut(void) { shiftin = false; };
void SetDirection(bool fromTop) { fromtop = fromTop; };
bool Tick(void);
};
/******************************************************************
* cBlinkable
* Blinking
******************************************************************/
class cBlinkable {
protected:
@@ -93,48 +219,49 @@ protected:
public:
virtual int BlinkFreq(int func) = 0;
virtual void DoBlink(int func, bool on) = 0;
virtual void RegisterAnimation(void) = 0;
virtual void UnregisterAnimation(void) = 0;
virtual void Flush(bool animFlush) = 0;
};
class cBlinker : public cAnimation {
private:
cBlinkable *blinkable;
int blinkFunc;
int freq;
bool blinkOn;
bool paused;
int pauseTime;
bool Pause(void);
public:
cBlinker(cBlinkable *blinkable, int blinkFunc);
~cBlinker(void);
void SetInitial(void);
void Reactivate(void);
bool Tick(void);
};
/******************************************************************
* cAnimation
* cAnimator
******************************************************************/
class cAnimation : public cThread, public cListObject {
class cAnimator : public cThread {
private:
cSdOsd *osd;
cCondWait sleepWait;
cScrollable *scrollable;
cDetachable *detachable;
cFadable *fadable;
cShiftable *shiftable;
cBlinkable *blinkable;
bool waitOnWakeup;
bool keepSleeping;
bool doAnimation;
bool modeIn;
int blinkFunc;
cPoint shiftstart;
cPoint shiftend;
void Sleep(int duration);
void Wait(void);
void Scroll(void);
void Detach(void);
void Blink(void);
protected:
cCondWait pauseWait;
int timeslice;
int timeneeded;
cMutex animLock;
cList<cAnimation> animations;
cList<cAnimation> animationsPersistent;
void Sleep(uint64_t start);
void DoTick(bool &animActive);
void CleanupAnims(void);
virtual void Action(void);
public:
cAnimation(cScrollable *scrollable);
cAnimation(cDetachable *detachable, bool wait, bool animation);
cAnimation(cFadable *fadable, bool fadein);
cAnimation(cShiftable *shiftable, cPoint &start, cPoint &end, bool shiftin);
cAnimation(cBlinkable *blinkable, int func);
~cAnimation(void);
void WakeUp(void);
void ResetSleep(void);
void Fade(void);
void Shift(void);
void Stop(bool deletePixmaps);
cAnimator(cSdOsd *osd);
~cAnimator(void);
void AddAnimation(cAnimation *animation, bool startAnim = true);
void RemoveAnimation(cAnimation *remove);
void Stop(void);
void Finish(void);
};
#endif //__ANIMATION_H

View File

@@ -251,6 +251,17 @@ void cArea::Clear(bool forceClearBackground) {
return;
}
StopBlinkers();
if (pix) {
pix->SetDrawPortPoint(cPoint(0,0));
pix->Fill(clrTransparent);
}
}
void cArea::ClearWithoutIndicators(void) {
if (attribs->IndicatorArea()) {
return;
}
StopBlinkers();
if (pix) {
pix->Fill(clrTransparent);
}
@@ -335,6 +346,23 @@ void cArea::SetTransparency(int transparency, bool absolute) {
}
}
void cArea::SetIndicatorTransparency(int transparency) {
if (!attribs->IndicatorArea())
return;
if (transparency < 0 || transparency > 100)
return;
int alpha = (100 - transparency)*255/100;
if (pix) {
pix->SetAlpha(alpha);
}
}
void cArea::SetIndicatorPosition(cPoint &pos) {
if (!attribs->IndicatorArea())
return;
SetDrawPort(pos);
}
bool cArea::Scrolling(void) {
if (!scrolling)
return false;
@@ -497,12 +525,6 @@ void cArea::Debug(bool full) {
}
}
void cArea::Flush(bool animFlush) {
if (animFlush)
sdOsd->AnimatedFlush();
else
sdOsd->Flush();
}
/******************************************************************
* Private Functions
******************************************************************/
@@ -565,9 +587,9 @@ void cArea::StartBlinkers(void) {
continue;
}
if (f->Blinking()) {
cAnimation *blink = new cAnimation((cBlinkable*)this, func);
blinkers.Add(blink);
blink->Start();
cBlinker *blinker = new cBlinker((cBlinkable*)this, func);
blinkers.push_back(blinker);
cView::AddAnimation(blinker);
}
func++;
}
@@ -575,15 +597,10 @@ void cArea::StartBlinkers(void) {
void cArea::StopBlinkers(void) {
blinking = false;
blinkers.Clear();
}
void cArea::RegisterAnimation(void) {
sdOsd->AddAnimation();
}
void cArea::UnregisterAnimation(void) {
sdOsd->RemoveAnimation();
for (list<cBlinker*>::iterator it = blinkers.begin(); it != blinkers.end(); it++) {
cView::RemoveAnimation(*it);
}
blinkers.clear();
}
/******************************************************************
@@ -707,6 +724,12 @@ void cAreaContainer::Clear(bool forceClearBackground) {
}
}
void cAreaContainer::ClearWithoutIndicators(void) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->ClearWithoutIndicators();
}
}
void cAreaContainer::Hide(void) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->Hide();
@@ -736,6 +759,18 @@ void cAreaContainer::SetTransparency(int transparency, bool absolute) {
}
}
void cAreaContainer::SetIndicatorTransparency(int transparency) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->SetIndicatorTransparency(transparency);
}
}
void cAreaContainer::SetIndicatorPosition(cPoint &pos) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->SetIndicatorPosition(pos);
}
}
void cAreaContainer::SetViewPort(cRect &vp) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->SetViewPort(vp);

View File

@@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <list>
#include "osdwrapper.h"
#include "definitions.h"
@@ -45,13 +46,16 @@ public:
virtual void Close(void) {};
virtual void StopBlinkers(void) {};
virtual void Clear(bool forceClearBackground = false) {};
virtual void ClearWithoutIndicators(void) {};
virtual void Hide(void) {};
virtual void Show(void) {};
virtual void Render(void) {};
virtual bool Execute(void) { return true; };
virtual void SetTransparency(int transparency, bool absolute = false) {};
virtual void SetIndicatorTransparency(int transparency) {};
virtual void SetViewPort(cRect &vp) {};
virtual void SetPosition(cPoint &pos, cPoint &ref) {};
virtual void SetIndicatorPosition(cPoint &pos) {};
virtual cRect CoveringArea(void) { return cRect::Null; };
virtual bool Scrolling(void) { return false; };
virtual cArea *ScrollingArea(void) { return NULL; };
@@ -77,7 +81,7 @@ private:
bool scrolling;
bool isScrolling;
cFunction *scrollFunc;
cList<cAnimation> blinkers;
list<cBlinker*> blinkers;
bool blinking;
void InitFunctions(void);
void CreatePixmap(cRect drawPort = cRect::Null);
@@ -105,11 +109,15 @@ public:
int GetWidth(void) { return attribs->Width(); };
void Close(void);
void Clear(bool forceClearBackground = false);
void ClearWithoutIndicators(void);
void Hide(void);
void Show(void);
void Render(void);
bool Execute(void);
bool IsIndicatorArea(void) { return attribs->IndicatorArea(); };
void SetTransparency(int transparency, bool absolute = false);
void SetIndicatorTransparency(int transparency);
void SetIndicatorPosition(cPoint &pos);
cRect CoveringArea(void);
//Scrollable
bool Scrolling(void);
@@ -133,11 +141,8 @@ public:
void DoBlink(int func, bool on);
void StopBlinkers(void);
//Common
void RegisterAnimation(void);
void UnregisterAnimation(void);
const char *Name(void) { return attribs->Name(); };
bool BackgroundArea(void) { return attribs->BackgroundArea(); };
void Flush(bool animFlush);
void Debug(bool full = false);
};
@@ -165,11 +170,14 @@ public:
void Cache(void);
void Close(void);
void Clear(bool forceClearBackground = false);
void ClearWithoutIndicators(void);
void Hide(void);
void Show(void);
void Render(void);
bool Execute(void);
void SetTransparency(int transparency, bool absolute = false);
void SetIndicatorTransparency(int transparency);
void SetIndicatorPosition(cPoint &pos);
void SetViewPort(cRect &vp);
void SetPosition(cPoint &pos, cPoint &ref);
cRect CoveringArea(void);

View File

@@ -359,6 +359,8 @@ void cAreaAttribs::Set(vector<stringpair> &attributes) {
SetScrollSpeed(id, attVal);
} else if (IdEqual(id, (int)eAreaAttribs::background)) {
SetBool(id, attVal);
} else if (IdEqual(id, (int)eAreaAttribs::indicator)) {
SetBool(id, attVal);
} else if (IdEqual(id, (int)eAreaAttribs::name)) {
name = new cTextExpr(attVal);
} else {
@@ -381,6 +383,13 @@ bool cAreaAttribs::BackgroundArea(void) {
return false;
}
bool cAreaAttribs::IndicatorArea(void) {
int isIndicator = GetValue((int)eAreaAttribs::indicator);
if (isIndicator == 1)
return true;
return false;
}
void cAreaAttribs::CheckDynamic(void) {
for (int i = (int)eCommonAttribs::x; i <= (int)eCommonAttribs::height; ++i ) {
if (attribCtors[i] && attribCtors[i]->Dynamic()) {
@@ -405,6 +414,7 @@ void cAreaAttribs::SetAttributesDefs(void) {
attribIDs.insert(pair<string, int>("scrollspeed", (int)eAreaAttribs::scrollspeed));
attribIDs.insert(pair<string, int>("delay", (int)eAreaAttribs::delay));
attribIDs.insert(pair<string, int>("background", (int)eAreaAttribs::background));
attribIDs.insert(pair<string, int>("indicator", (int)eAreaAttribs::indicator));
attribIDs.insert(pair<string, int>("name", (int)eAreaAttribs::name));
attribIDs.insert(pair<string, int>("scrollheight", (int)eAreaAttribs::scrollheight));
attribNames.insert(pair<int, string>((int)eAreaAttribs::layer, "layer"));

View File

@@ -96,6 +96,7 @@ public:
int Layer(void);
int ScrollStep(void) { return GetValue((int)eAreaAttribs::scrollheight); };
bool BackgroundArea(void);
bool IndicatorArea(void);
const char *Name(void);
void CheckDynamic(void);
bool Dynamic(void) {return dynamic; };

View File

@@ -1677,6 +1677,7 @@ enum class eAreaAttribs {
scrollspeed,
delay,
background,
indicator,
name,
scrollheight,
count

View File

@@ -13,15 +13,24 @@ cListElement::cListElement(void) {
current = false;
wasCurrent = false;
selectable = false;
selectedFromTop = true;
suppressAnimation = false;
listShifter = NULL;
currentElement = NULL;
menuCat = mcUndefined;
orientation = eOrientation::vertical;
};
cListElement::cListElement(const cListElement &other) : cViewElement(other) {
num = -1;
current = false;
wasCurrent = false;
selectable = false;
selectedFromTop = true;
suppressAnimation = false;
listShifter = NULL;
currentElement = NULL;
orientation = eOrientation::vertical;
}
void cListElement::SetCurrent(bool cur) {
@@ -54,6 +63,80 @@ void cListElement::WakeCurrent(void) {
}
}
void cListElement::Render(void) {
if (!dirty || blocked)
return;
if (attribs->DoDebug())
Debug();
bool animated = Fading() || Shifting();
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;
}
}
//don't clear animated list element if it was current
//and animation was not suppressed because of cleared list
sdOsd->Lock();
if (animated && wasCurrent && !suppressAnimation) {
node->ClearWithoutIndicators();
} else {
node->Clear();
}
sdOsd->Unlock();
if (!node->Execute())
continue;
sdOsd->Lock();
node->Render();
sdOsd->Unlock();
if (DoScroll() && node->Scrolling()) {
cArea *scrollArea = node->ScrollingArea();
if (scrollArea) {
scrollingStarted = true;
cScroller *scroller = new cScroller(scrollArea);
scrollers.push_back(scroller);
cView::AddAnimation(scroller);
}
}
}
dirty = false;
drawn = true;
StartListAnimation();
}
int cListElement::ShiftDistance(void) {
if (orientation == eOrientation::horizontal)
return container.Width();
return container.Height();
}
eOrientation cListElement::ShiftOrientation(void) {
return orientation;
}
void cListElement::SetIndicatorPosition(cPoint &position) {
for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) {
sdOsd->Lock();
node->SetIndicatorPosition(position);
sdOsd->Unlock();
}
}
void cListElement::SetTransparency(int transparency, bool force) {
for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) {
sdOsd->Lock();
node->SetIndicatorTransparency(transparency);
sdOsd->Unlock();
}
}
char *cListElement::ParseSeparator(const char *text) {
const char *start = text;
@@ -71,6 +154,49 @@ char *cListElement::ParseSeparator(const char *text) {
return ret;
}
void cListElement::StopListAnimation(void) {
if (listShifter) {
cView::RemoveAnimation(listShifter);
listShifter = NULL;
}
if (fader) {
cView::RemoveAnimation(fader);
fader = NULL;
}
}
void cListElement::StartListAnimation(void) {
if (suppressAnimation)
return;
if (!Fading() && !Shifting())
return;
listShifter = NULL;
fader = NULL;
if (current) {
if (ShiftTime() > 0) {
listShifter = new cListShifter((cListShiftable*)this);
listShifter->SetDirection(selectedFromTop);
cView::AddAnimation(listShifter, true);
} else if (FadeTime() > 0) {
fader = new cFader((cFadable*)this);
cView::AddAnimation(fader, true);
}
}
if (wasCurrent) {
if (ShiftTime() > 0) {
listShifter = new cListShifter((cListShiftable*)this);
listShifter->SetDirection(selectedFromTop);
listShifter->SetShiftOut();
cView::AddAnimation(listShifter, false);
} else if (FadeTime() > 0) {
fader = new cFader((cFadable*)this);
fader->SetFadeOut();
fader->SetHideWhenFinished();
cView::AddAnimation(fader, false);
}
}
}
/******************************************************************
* cCurrentElement
******************************************************************/

View File

@@ -8,28 +8,45 @@
/******************************************************************
* cListElement
******************************************************************/
class cListElement : public cViewElement {
class cListElement : public cViewElement , public cListShiftable {
protected:
eMenuCategory menuCat;
eOrientation orientation;
int num;
bool current;
bool wasCurrent;
bool selectable;
bool selectedFromTop;
bool suppressAnimation;
cListShifter *listShifter;
cViewElement *currentElement;
char *ParseSeparator(const char *text);
void StartListAnimation(void);
public:
cListElement(void);
cListElement(const cListElement &other);
virtual ~cListElement(void) {};
void SetMenuCategory(eMenuCategory menuCat) { this->menuCat = menuCat; };
void SetOrientation(eOrientation orientation) { this->orientation = orientation; };
void SetNumber(int number) { num = number; };
void SetCurrent(bool cur);
bool Current(void) { return current; };
bool WasCurrent(void) { return wasCurrent; };
void WakeCurrent(void);
void SetSelectable(bool sel) { selectable = sel; };
void SetSelectedFromTop(void) { selectedFromTop = true; };
void SetSelectedFromBottom(void) { selectedFromTop = false; };
void SetSuppressAnimation(bool suppress) { suppressAnimation = suppress; };
bool DoScroll(void) { return current; };
void Render(void);
virtual void RenderCurrent(void) { };
void Close(void);
int ListShiftTime(void) { return ShiftTime(); };
int ShiftDistance(void);
eOrientation ShiftOrientation(void);
void SetIndicatorPosition(cPoint &position);
void SetTransparency(int transparency, bool force = false);
void StopListAnimation(void);
virtual void Clear(bool forceClearBackground = false);
};

View File

@@ -2,9 +2,6 @@
cSdOsd::cSdOsd(void) {
osd = NULL;
flushLocked = false;
animsRunning = 0;
animsFlushed = 0;
}
cSdOsd::~cSdOsd(void) {
@@ -19,18 +16,6 @@ void cSdOsd::Unlock(void) {
mutex.Unlock();
}
void cSdOsd::LockFlush(void) {
Lock();
flushLocked = true;
Unlock();
}
void cSdOsd::UnlockFlush(void) {
Lock();
flushLocked = false;
Unlock();
}
bool cSdOsd::CreateOsd(int x, int y, int width, int height) {
cOsd *newOsd = cOsdProvider::NewOsd(cOsd::OsdLeft() + x, cOsd::OsdTop() + y);
if (newOsd) {
@@ -50,10 +35,6 @@ void cSdOsd::DeleteOsd(void) {
delete osd;
osd = NULL;
Unlock();
animsRunningMutex.Lock();
animsRunning = 0;
animsFlushed = 0;
animsRunningMutex.Unlock();
}
cPixmap *cSdOsd::CreatePixmap(int layer, cRect &viewPort, cRect &drawPort) {
@@ -69,33 +50,8 @@ void cSdOsd::DestroyPixmap(cPixmap *pix) {
}
}
void cSdOsd::AddAnimation(void) {
animsRunningMutex.Lock();
animsRunning++;
animsRunningMutex.Unlock();
}
void cSdOsd::RemoveAnimation(void) {
animsRunningMutex.Lock();
animsRunning--;
animsRunningMutex.Unlock();
}
void cSdOsd::AnimatedFlush(void) {
if (osd && !flushLocked) {
animsRunningMutex.Lock();
if (animsFlushed + 1 >= animsRunning) {
animsFlushed = 0;
osd->Flush();
} else {
animsFlushed++;
}
animsRunningMutex.Unlock();
}
}
void cSdOsd::Flush(void) {
if (osd && !flushLocked) {
if (osd) {
osd->Flush();
}
}

View File

@@ -8,24 +8,15 @@ class cSdOsd {
private:
cOsd *osd;
cMutex mutex;
bool flushLocked;
int animsRunning;
int animsFlushed;
cMutex animsRunningMutex;
public:
cSdOsd(void);
virtual ~cSdOsd(void);
void Lock(void);
void Unlock(void);
void LockFlush(void);
void UnlockFlush(void);
bool CreateOsd(int x, int y, int width, int height);
void DeleteOsd(void);
cPixmap *CreatePixmap(int layer, cRect &viewPort, cRect &drawPort);
void DestroyPixmap(cPixmap *pix);
void AddAnimation(void);
void RemoveAnimation(void);
void AnimatedFlush(void);
void Flush(void);
};

View File

@@ -3,6 +3,8 @@
// --- cView -------------------------------------------------------------
cAnimator* cView::animator = NULL;
cView::cView(void) {
globals = NULL;
viewName = NULL;
@@ -10,8 +12,6 @@ cView::cView(void) {
numViewElements = 0;
viewElements = NULL;
viewElementsHorizontal = NULL;
fader = NULL;
shifter = NULL;
shifting = false;
currentTvFrame = NULL;
newTvFrame = NULL;
@@ -29,8 +29,8 @@ cView::~cView() {
}
delete attribs;
free(viewName);
delete fader;
delete shifter;
delete animator;
animator = NULL;
shifting = false;
sdOsd.DeleteOsd();
}
@@ -203,11 +203,24 @@ void cView::PreCache(void) {
SetViewElementObjects();
}
void cView::AddAnimation(cAnimation *animation, bool startAnimation) {
if (!animator)
return;
animator->AddAnimation(animation, startAnimation);
}
void cView::RemoveAnimation(cAnimation *animation) {
if (!animator)
return;
animator->RemoveAnimation(animation);
}
bool cView::Init(void) {
int osdX = attribs->X();
int osdY = attribs->Y();
int osdWidth = attribs->Width();
int osdHeight = attribs->Height();
animator = new cAnimator(&sdOsd);
return sdOsd.CreateOsd(osdX, osdY, osdWidth, osdHeight);
}
@@ -243,24 +256,19 @@ void cView::Show(int ve) {
viewElements[ve]->Show();
}
void cView::SetViewelementsAnimOut(void) {
for (int i=0; i< numViewElements; i++)
if (viewElements[i]) {
viewElements[i]->SetAnimOut();
}
}
void cView::Close(void) {
delete fader;
fader = NULL;
delete shifter;
shifter = NULL;
if (initFinished && ShiftTime() > 0) {
cRect shiftbox = CoveredArea();
cPoint ref = cPoint(shiftbox.X(), shiftbox.Y());
cPoint end = ShiftStart(shiftbox);
shifter = new cAnimation((cShiftable*)this, end, ref, false);
shifter->Shift();
delete shifter;
shifter = NULL;
} else if (initFinished && FadeTime() > 0) {
fader = new cAnimation((cFadable*)this, false);
fader->Fade();
delete fader;
fader = NULL;
if (animator) {
animator->Stop();
animator->Finish();
delete animator;
animator = NULL;
}
UnScaleTv();
ClearVariables();
@@ -293,6 +301,13 @@ int cView::ShiftMode(void) {
return attribs->ShiftMode();
}
void cView::ShiftPositions(cPoint *start, cPoint *end) {
cRect shiftbox = CoveredArea();
cPoint startPoint = ShiftStart(shiftbox);
start->Set(startPoint);
end->Set(shiftbox.X(), shiftbox.Y());
}
void cView::SetPosition(cPoint &position, cPoint &reference, bool force) {
for (int i = 0; i < numViewElements; i++) {
if (viewElements[i] && (!viewElements[i]->Shifting() || force)) {
@@ -301,32 +316,18 @@ void cView::SetPosition(cPoint &position, cPoint &reference, bool force) {
}
}
void cView::RegisterAnimation(void) {
sdOsd.AddAnimation();
}
void cView::UnregisterAnimation(void) {
sdOsd.RemoveAnimation();
}
void cView::Flush(bool animFlush) {
void cView::Flush(void) {
if (init) {
init = false;
StartAnimation();
menuInit = true;
//LockFlush was set at startup of view to avoid display
//of not positioned pixmaps for shifting and fading
sdOsd.UnlockFlush();
}
if (menuInit) {
ScaleTv();
WakeViewElements();
menuInit = false;
}
if (animFlush)
sdOsd.AnimatedFlush();
else
sdOsd.Flush();
sdOsd.Flush();
}
void cView::Debug(void) {
@@ -345,7 +346,6 @@ void cView::Debug(void) {
*******************************************************************/
void cView::ClearVariables(void) {
init = true;
initFinished = false;
newTvFrame = NULL;
currentTvFrame = NULL;
menuInit = false;
@@ -359,22 +359,19 @@ int cView::ViewElementId(const char *name) {
}
void cView::StartAnimation(void) {
if (ShiftTime() > 0) {
cRect shiftbox = CoveredArea();
cPoint ref = cPoint(shiftbox.X(), shiftbox.Y());
cPoint start = ShiftStart(shiftbox);
SetPosition(start, ref);
shifter = new cAnimation((cShiftable*)this, start, ref, true);
shifter->Start();
} else if (FadeTime() > 0) {
if (fader)
return;
SetTransparency(100);
sdOsd.Flush();
fader = new cAnimation((cFadable*)this, true);
fader->Start();
if (viewId != eViewType::DisplayMenu &&
viewId != eViewType::DisplayPlugin) {
if (ShiftTime() > 0) {
cShifter *shifter = new cShifter((cShiftable*)this);
shifter->SetPersistent();
cView::AddAnimation(shifter);
} else if (FadeTime() > 0) {
cFader *fader = new cFader((cFadable*)this);
fader->SetPersistent();
cView::AddAnimation(fader);
}
}
initFinished = true;
animator->Start();
}
void cView::WakeViewElements(void) {

View File

@@ -29,10 +29,10 @@ private:
void SetClearOnDisplay(int ve, const char *clearOnDisplay);
protected:
cSdOsd sdOsd;
static cAnimator *animator;
cViewAttribs *attribs;
cRect container;
bool init;
bool initFinished;
eViewType viewId;
cGlobals *globals;
char *viewName;
@@ -40,8 +40,6 @@ protected:
cViewElement **viewElements;
cViewElement **viewElementsHorizontal;
map<string,int> viewElementNames;
cAnimation *fader;
cAnimation *shifter;
bool shifting;
cRect tvFrame;
cRect *currentTvFrame;
@@ -74,6 +72,8 @@ public:
virtual const cFont *GetTextAreaFont(void) { return NULL; };
virtual int GetTextAreaWidth(void) { return 0; };
virtual int GetListWidth(void) { return 0; };
static void AddAnimation(cAnimation *animation, bool startAnimation = true);
static void RemoveAnimation(cAnimation *animation);
//View API
virtual bool Init(void);
void Clear(int ve, bool forceClearBackground = false);
@@ -82,21 +82,20 @@ public:
void Hide(int ve);
void Show(int ve);
virtual void Close(void);
virtual void Flush(bool animFlush);
virtual void Flush(void);
virtual void Debug(void);
void SetViewelementsAnimOut(void);
//Fadable
bool Detached(void) { return false; };
int Delay(void) { return 0; };
int FadeTime(void);
virtual void SetTransparency(int transparency, bool force = false);
//Shiftable
int ShiftTime(void);
int ShiftMode(void);
void ShiftPositions(cPoint *start, cPoint *end);
virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false);
void SetStartShifting(void) { shifting = true; };
void SetEndShifting(void) { shifting = false; };
void RegisterAnimation(void);
void UnregisterAnimation(void);
};
#endif //__VIEW_H

View File

@@ -71,6 +71,13 @@ void cViewChannel::PreCache(void) {
groupChannelList->PreCache();
}
#endif
if (viewElements[(int)eVeDisplayChannel::channellistback])
viewElements[(int)eVeDisplayChannel::channellistback]->UnsetStartAnim();
if (viewElements[(int)eVeDisplayChannel::grouplistback])
viewElements[(int)eVeDisplayChannel::grouplistback]->UnsetStartAnim();
if (viewElements[(int)eVeDisplayChannel::groupchannellistback])
viewElements[(int)eVeDisplayChannel::groupchannellistback]->UnsetStartAnim();
SetViewelementsAnimOut();
}
void cViewChannel::AddChannelViewList(const char *listName, cViewList *viewList) {
@@ -363,29 +370,17 @@ void cViewChannel::SetChannelHint(const cChannel *channel) {
#endif //USE_ZAPCOCKPIT
void cViewChannel::Close(void) {
delete fader;
fader = NULL;
delete shifter;
shifter = NULL;
bool doAnim = true;
#ifdef USE_ZAPCOCKPIT
if (viewType != dcDefault)
doAnim = false;
#endif
if (initFinished && doAnim && ShiftTime() > 0) {
cRect shiftbox = CoveredArea();
cPoint ref = cPoint(shiftbox.X(), shiftbox.Y());
cPoint end = ShiftStart(shiftbox);
shifter = new cAnimation((cShiftable*)this, end, ref, false);
shifter->Shift();
delete shifter;
shifter = NULL;
} else if (initFinished && doAnim && FadeTime() > 0) {
fader = new cAnimation((cFadable*)this, false);
fader->Fade();
delete fader;
fader = NULL;
if (doAnim) {
animator->Stop();
animator->Finish();
}
delete animator;
animator = NULL;
UnScaleTv();
ClearVariables();
for (int i=0; i < numViewElements; i++) {
@@ -557,8 +552,6 @@ void cViewChannel::DrawExtended(void) {
ClearOnDisplay();
initExtended = false;
}
if (!init && initList)
sdOsd.LockFlush();
if (viewType == dcChannelList && channelList) {
Render((int)eVeDisplayChannel::channellistback);
channelList->Draw(mcUndefined);
@@ -575,27 +568,22 @@ void cViewChannel::DrawExtended(void) {
if (initList)
groupChannelList->StartAnimation();
}
if (!init && initList)
sdOsd.UnlockFlush();
displayList = false;
initList = false;
#endif
}
void cViewChannel::Flush(bool animFlush) {
if (init) {
sdOsd.LockFlush();
}
void cViewChannel::Flush(void) {
#ifdef USE_ZAPCOCKPIT
ClearExtended();
#endif
#ifdef USE_ZAPCOCKPIT
if (viewType < dcChannelList) {
#endif
//Basic Display Handling
if (mode == dmDefault) {
if (!shifting) {
DrawBasic(init);
}
DrawBasic(init);
} else if (mode == dmChannelGroups) {
if (init) {
Render((int)eVeDisplayChannel::background);
@@ -603,15 +591,16 @@ void cViewChannel::Flush(bool animFlush) {
}
Render((int)eVeDisplayChannel::channelgroup);
}
if (!shifting) {
Render((int)eVeDisplayChannel::datetime);
Render((int)eVeDisplayChannel::time);
Render((int)eVeDisplayChannel::datetime);
Render((int)eVeDisplayChannel::time);
#ifdef USE_ZAPCOCKPIT
}
#endif
channelChange = false;
#ifdef USE_ZAPCOCKPIT
DrawExtended();
#endif
cView::Flush(animFlush);
cView::Flush();
}

View File

@@ -71,7 +71,7 @@ public:
void SetChannelHint(const cChannel *channel);
#endif
void Close(void);
void Flush(bool animFlush);
void Flush(void);
};
#endif //__VIEWDISPLAYCHANNEL_H

View File

@@ -535,14 +535,10 @@ bool cViewMenu::Init(void) {
}
void cViewMenu::Close(void) {
delete fader;
fader = NULL;
if (FadeTime() > 0) {
fader = new cAnimation((cFadable*)this, false);
fader->Fade();
delete fader;
fader = NULL;
}
animator->Stop();
animator->Finish();
delete animator;
animator = NULL;
for (int i=0; i < numSubviews; i++) {
if (subViews[i]) {
subViews[i]->Close();
@@ -566,10 +562,7 @@ void cViewMenu::Clear(void) {
activeSubview->ClearViewList();
}
void cViewMenu::Flush(bool animFlush) {
if (init) {
sdOsd.LockFlush();
}
void cViewMenu::Flush(void) {
bool staticInitiated = false;
if (menuChange) {
newTvFrame = activeSubview->GetTvFrame();
@@ -591,7 +584,7 @@ void cViewMenu::Flush(bool animFlush) {
detailViewInit = false;
}
activeSubview->DrawDynamicVEs();
cView::Flush(animFlush);
cView::Flush();
}
void cViewMenu::SetTransparency(int transparency, bool forceDetached) {
@@ -912,6 +905,7 @@ void cSubView::DrawDynamicVEs(void) {
void cSubView::DrawList(void) {
if (viewList) {
viewList->Draw(menuCat);
viewList->ResetItemCount();
}
}

View File

@@ -101,7 +101,7 @@ public:
bool Init(void);
void Close(void);
void Clear(void);
void Flush(bool animFlush);
void Flush(void);
void SetTransparency(int transparency, bool forceDetached = false);
void Debug(void);
};

View File

@@ -43,12 +43,11 @@ void cViewMessage::SetMessage(eMessageType type, const char *text) {
veMessage->Set(type, text);
}
void cViewMessage::Flush(bool animFlush) {
void cViewMessage::Flush(void) {
if (init) {
sdOsd.LockFlush();
Render((int)eVeDisplayMessage::background);
}
Render((int)eVeDisplayMessage::message);
cView::Flush(animFlush);
cView::Flush();
}

View File

@@ -13,7 +13,7 @@ public:
cViewMessage(void);
virtual ~cViewMessage(void);
void SetMessage(eMessageType type, const char *text);
void Flush(bool animFlush);
void Flush(void);
};
#endif //__VIEWDISPLAYMESSAGE_H

View File

@@ -352,13 +352,13 @@ void cViewPlugin::ClearTab(int viewId) {
tab->Clear();
}
void cViewPlugin::Flush(bool animFlush) {
void cViewPlugin::Flush(void) {
if (viewChanged) {
viewChanged = false;
newTvFrame = views[newViewId]->GetTvFrame();
menuInit = true;
}
cView::Flush(animFlush);
cView::Flush();
}
bool cViewPlugin::ChannelLogoExists(string channelId) {

View File

@@ -64,7 +64,7 @@ public:
void TabDown(int viewId);
void DisplayTabs(int viewId);
void ClearTab(int viewId);
void Flush(bool animFlush);
void Flush(void);
bool ChannelLogoExists(string channelId);
string GetEpgImagePath(void);
};

View File

@@ -135,6 +135,11 @@ void cViewReplay::SetViewElementObjects(void) {
}
}
void cViewReplay::PreCache(void) {
cView::PreCache();
SetViewelementsAnimOut();
}
void cViewReplay::ClearVariables(void) {
cView::ClearVariables();
modeOnly = false;
@@ -276,9 +281,8 @@ void cViewReplay::DelayOnPause(void) {
veOnPause->ResetSleep();
}
void cViewReplay::Flush(bool animFlush) {
void cViewReplay::Flush(void) {
if (init) {
sdOsd.LockFlush();
if (!modeOnly) {
Render((int)eVeDisplayReplay::background);
Render((int)eVeDisplayReplay::rectitle);
@@ -303,7 +307,7 @@ void cViewReplay::Flush(bool animFlush) {
SetProgressModeOnly();
}
cView::Flush(animFlush);
cView::Flush();
}
void cViewReplay::SetProgressModeOnly(void) {
@@ -326,4 +330,4 @@ void cViewReplay::SetProgressModeOnly(void) {
veProgressModeOnly->Set(fps, current, total);
if (veProgressModeOnly->Parse())
veProgressModeOnly->Render();
}
}

View File

@@ -37,6 +37,7 @@ private:
public:
cViewReplay(void);
virtual ~cViewReplay(void);
void PreCache(void);
void SetModeOnly(bool modeOnly) { this->modeOnly = modeOnly; };
void SetRecordingLength(int length) { reclength = length; };
void SetTimeShift(int framesTotal, int timeShiftLength);
@@ -53,7 +54,7 @@ public:
void StartOnPause(const char *recfilename);
void ClearOnPause(void);
void DelayOnPause(void);
void Flush(bool animFlush);
void Flush(void);
};
#endif //__VIEWDISPLAYREPLAY_H1

View File

@@ -41,14 +41,10 @@ void cViewTracks::ClearVariables(void) {
}
void cViewTracks::Close(void) {
delete fader;
fader = NULL;
if (FadeTime() > 0) {
fader = new cAnimation((cFadable*)this, false);
fader->Fade();
delete fader;
fader = NULL;
}
animator->Stop();
animator->Finish();
delete animator;
animator = NULL;
for (int i=0; i < numViewElements; i++) {
if (viewElements[i]) {
viewElements[i]->Close();
@@ -107,14 +103,13 @@ void cViewTracks::SetCurrentTrack(int index) {
change = true;
}
void cViewTracks::Flush(bool animFlush) {
void cViewTracks::Flush(void) {
if (init) {
sdOsd.LockFlush();
Render((int)eVeDisplayTracks::background);
if (viewList) {
viewList->Draw();
viewList->StartAnimation();
viewList->StartAnimation(true);
}
Render((int)eVeDisplayTracks::background);
}
if (change) {
Render((int)eVeDisplayTracks::header);
@@ -122,5 +117,5 @@ void cViewTracks::Flush(bool animFlush) {
viewList->Draw();
change = false;
}
cView::Flush(animFlush);
cView::Flush();
}

View File

@@ -23,7 +23,7 @@ public:
void SetTracks(const char * const *tracks);
void SetAudiochannel(int audioChannel);
void SetCurrentTrack(int index);
void Flush(bool animFlush);
void Flush(void);
};
#endif //__VIEWDISPLAYTRACKS_H

View File

@@ -40,13 +40,12 @@ void cViewVolume::SetVolume(int current, int total, bool mute) {
veVolume->Set(current, total, mute);
}
void cViewVolume::Flush(bool animFlush) {
void cViewVolume::Flush(void) {
if (init) {
sdOsd.LockFlush();
Render((int)eVeDisplayVolume::background);
}
Render((int)eVeDisplayVolume::volume);
cView::Flush(animFlush);
cView::Flush();
}

View File

@@ -13,7 +13,7 @@ public:
cViewVolume(void);
virtual ~cViewVolume(void);
void SetVolume(int current, int total, bool mute);
void Flush(bool animFlush);
void Flush(void);
};
#endif //__VIEWDISPLAYVOLUME_H

View File

@@ -13,6 +13,8 @@ cViewElement::cViewElement(void) {
scrollingStarted = false;
blocked = false;
detached = false;
doAnimOut = false;
doStartAnim = true;
waitOnWakeup = true;
startAnimation = true;
restartAnimation = false;
@@ -21,8 +23,8 @@ cViewElement::cViewElement(void) {
attribs = new cViewElementAttribs((int)eViewElementAttribs::count);
clearAll = false;
detacher = NULL;
fader = NULL;
shifter = NULL;
fader = NULL;
}
cViewElement::cViewElement(const cViewElement &other) {
@@ -34,6 +36,8 @@ cViewElement::cViewElement(const cViewElement &other) {
scrollingStarted = false;
blocked = false;
detached = false;
doAnimOut = other.doAnimOut;
doStartAnim = other.doStartAnim;
waitOnWakeup = true;
startAnimation = true;
restartAnimation = false;
@@ -52,15 +56,13 @@ cViewElement::cViewElement(const cViewElement &other) {
}
detacher = NULL;
fader = NULL;
shifter = NULL;
fader = NULL;
}
cViewElement::~cViewElement(void) {
delete attribs;
delete detacher;
delete fader;
delete shifter;
delete tokenContainer;
}
@@ -381,9 +383,9 @@ void cViewElement::Render(void) {
cArea *scrollArea = node->ScrollingArea();
if (scrollArea) {
scrollingStarted = true;
cAnimation *scroller = new cAnimation(scrollArea);
scrollers.Add(scroller);
scroller->Start();
cScroller *scroller = new cScroller(scrollArea);
scrollers.push_back(scroller);
cView::AddAnimation(scroller);
}
}
}
@@ -397,10 +399,10 @@ void cViewElement::Render(void) {
}
void cViewElement::StopScrolling(bool deletePixmaps) {
for (cAnimation *scroller = scrollers.First(); scroller; scroller = scrollers.Next(scroller)) {
scroller->Stop(deletePixmaps);
for (list<cScroller*>::iterator it = scrollers.begin(); it != scrollers.end(); it++) {
cView::RemoveAnimation(*it);
}
scrollers.Clear();
scrollers.clear();
}
void cViewElement::ParseDetached(void) {
@@ -413,14 +415,14 @@ void cViewElement::RenderDetached(void) {
}
bool cViewElement::Shifting(void) {
if (attribs->ShiftTime() >= 0) {
if (attribs->ShiftTime() > 0) {
return true;
}
return false;
}
bool cViewElement::Fading(void) {
if (attribs->FadeTime() >= 0) {
if (attribs->FadeTime() > 0) {
return true;
}
return false;
@@ -438,22 +440,26 @@ int cViewElement::ShiftMode(void) {
return attribs->ShiftMode();
}
void cViewElement::ShiftPositions(cPoint *start, cPoint *end) {
cRect shiftbox = CoveredArea();
cPoint startPoint = ShiftStart(shiftbox);
start->Set(startPoint);
end->Set(shiftbox.X(), shiftbox.Y());
}
void cViewElement::StartAnimation(void) {
shifter = NULL;
fader = NULL;
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();
shifter = new cShifter((cShiftable*)this);
if (doAnimOut)
shifter->SetPersistent();
cView::AddAnimation(shifter, doStartAnim);
} else if (FadeTime() > 0) {
SetTransparency(100);
sdOsd->Flush();
delete fader;
fader = new cAnimation((cFadable*)this, true);
fader->Start();
fader = new cFader((cFadable*)this);
if (doAnimOut)
fader->SetPersistent();
cView::AddAnimation(fader, doStartAnim);
}
}
@@ -481,19 +487,8 @@ cRect cViewElement::CoveredArea(void) {
return unionArea;
}
void cViewElement::RegisterAnimation(void) {
sdOsd->AddAnimation();
}
void cViewElement::UnregisterAnimation(void) {
sdOsd->RemoveAnimation();
}
void cViewElement::Flush(bool animFlush) {
if (animFlush)
sdOsd->AnimatedFlush();
else
sdOsd->Flush();
void cViewElement::Flush(void) {
sdOsd->Flush();
}
bool cViewElement::Parse(bool forced) {
@@ -505,7 +500,7 @@ bool cViewElement::Parse(bool forced) {
}
delete detacher;
bool isAnimated = (FadeTime() > 0) || (ShiftTime() > 0);
detacher = new cAnimation((cDetachable*)this, waitOnWakeup, startAnimation && isAnimated);
detacher = new cDetacher((cDetachable*)this, waitOnWakeup, startAnimation && isAnimated);
detacher->Start();
startAnimation = false;
init = false;
@@ -576,8 +571,8 @@ cPoint cViewElement::ShiftStart(cRect &shiftbox) {
void cViewElement::StopAnimation(void) {
delete detacher;
detacher = NULL;
delete shifter;
shifter = NULL;
delete fader;
fader = NULL;
if (shifter)
cView::RemoveAnimation(shifter);
if (fader)
cView::RemoveAnimation(fader);
}

View File

@@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <list>
#include <vdr/tools.h>
#include "osdwrapper.h"
#include "globals.h"
@@ -24,6 +25,8 @@ protected:
bool dirty;
bool blocked;
bool detached;
bool doAnimOut;
bool doStartAnim;
bool waitOnWakeup;
bool scrollingStarted;
bool startAnimation;
@@ -35,10 +38,10 @@ protected:
bool clearAll;
cList<cAreaNode> areaNodes;
skindesignerapi::cTokenContainer *tokenContainer;
cList<cAnimation> scrollers;
cAnimation *detacher;
cAnimation *fader;
cAnimation *shifter;
list<cScroller*> scrollers;
cDetacher *detacher;
cShifter *shifter;
cFader *fader;
void InheritTokenContainer(void);
void InheritTokenContainerDeep(void);
virtual bool DoScroll(void) { return true; };
@@ -54,6 +57,8 @@ public:
void SetGlobals(cGlobals *globals);
virtual void SetTokenContainer(void);
void SetDetached(void) { detached = true; };
void SetAnimOut(void) { doAnimOut = true; };
void UnsetStartAnim(void) { doStartAnim = false; };
void UnsetWaitOnWakeup(void) { waitOnWakeup = false; };
bool Detached(void);
void SetContainer(int x, int y, int width, int height);
@@ -90,16 +95,15 @@ public:
int FadeTime(void);
int ShiftTime(void);
int ShiftMode(void);
void ShiftPositions(cPoint *start, cPoint *end);
void StartAnimation(void);
void SetRestartAnimation(void) { restartAnimation = true; };
virtual void SetTransparency(int transparency, bool force = false);
virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false);
void SetStartShifting(void) { };
void SetEndShifting(void) { };
void RegisterAnimation(void);
void UnregisterAnimation(void);
cRect CoveredArea(void);
void Flush(bool animFlush);
void Flush(void);
virtual bool Parse(bool forced = false);
cFunction *GetFunction(const char *name);
virtual void Debug(bool full = false);

View File

@@ -1,9 +1,13 @@
#include "viewlist.h"
#include "view.h"
cViewList::cViewList(void) {
globals = NULL;
attribs = new cViewListAttribs((int)eViewListAttribs::count);
numElements = 0;
orientation = eOrientation::vertical;
cleared = true;
itemCount = 0;
listElement = NULL;
currentElement = NULL;
listElements = NULL;
@@ -27,8 +31,6 @@ cViewList::~cViewList(void) {
}
delete[] listElements;
delete tokenContainer;
delete fader;
delete shifter;
}
void cViewList::SetGlobals(cGlobals *globals) {
@@ -194,9 +196,15 @@ eOrientation cViewList::Orientation(void) {
void cViewList::Draw(eMenuCategory menuCat) {
int current = -1;
int numCalls = 0;
for (int i = 0; i < numElements; i++) {
listElements[i]->SetMenuCategory(menuCat);
if (listElements[i]->Parse()) {
if (listElements[i]->Shifting())
SetShiftParameters(i, numCalls);
if (listElements[i]->Fading() && itemCount == 1) {
listElements[i]->SetSuppressAnimation(true);
}
listElements[i]->Render();
if (listElements[i]->Current()) {
listElements[i]->RenderCurrent();
@@ -207,10 +215,11 @@ void cViewList::Draw(eMenuCategory menuCat) {
if (current >= 0 && listElements[current]) {
listElements[current]->WakeCurrent();
}
cleared = false;
}
void cViewList::Clear(void) {
cleared = true;
if (!listElements)
return;
for (int i = 0; i < numElements; i++) {
@@ -223,10 +232,10 @@ void cViewList::Clear(void) {
}
void cViewList::Close(void) {
delete fader;
fader = NULL;
delete shifter;
shifter = NULL;
if (shifter)
cView::RemoveAnimation(shifter);
if (fader)
cView::RemoveAnimation(fader);
if (!listElements)
return;
for (int i = 0; i < numElements; i++) {
@@ -260,49 +269,26 @@ void cViewList::SetPosition(cPoint &position, cPoint &reference, bool force) {
}
}
void cViewList::RegisterAnimation(void) {
for (int i = 0; i < numElements; i++) {
if (listElements[i]) {
listElements[i]->RegisterAnimation();
break;
}
}
void cViewList::ShiftPositions(cPoint *start, cPoint *end) {
cRect shiftbox = CoveredArea();
cPoint startPoint = ShiftStart(shiftbox);
start->Set(startPoint);
end->Set(shiftbox.X(), shiftbox.Y());
}
void cViewList::UnregisterAnimation(void) {
for (int i = 0; i < numElements; i++) {
if (listElements[i]) {
listElements[i]->UnregisterAnimation();
break;
}
}
}
void cViewList::StartAnimation(void) {
void cViewList::StartAnimation(bool animOut) {
shifter = NULL;
fader = NULL;
if (ShiftTime() > 0) {
cRect shiftbox = CoveredArea();
cPoint ref = cPoint(shiftbox.X(), shiftbox.Y());
cPoint start = ShiftStart(shiftbox);
SetPosition(start, ref);
Flush(false);
delete shifter;
shifter = new cAnimation((cShiftable*)this, start, ref, true);
shifter->Start();
shifter = new cShifter((cShiftable*)this);
if (animOut)
shifter->SetPersistent();
cView::AddAnimation(shifter);
} else if (FadeTime() > 0) {
SetTransparency(100);
Flush(false);
delete fader;
fader = new cAnimation((cFadable*)this, true);
fader->Start();
}
}
void cViewList::Flush(bool animFlush) {
for (int i = 0; i < numElements; i++) {
if (listElements[i]) {
listElements[i]->Flush(animFlush);
break;
}
fader = new cFader((cFadable*)this);
if (animOut)
fader->SetPersistent();
cView::AddAnimation(fader);
}
}
@@ -332,6 +318,37 @@ cPoint cViewList::ShiftStart(cRect &shiftbox) {
return start;
}
void cViewList::SetShiftParameters(int index, int &call) {
if (itemCount == 1) {
listElements[index]->SetSuppressAnimation(true);
return;
}
listElements[index]->SetSuppressAnimation(cleared);
if (listElements[index]->WasCurrent()) {
if (call == 0) {
call++;
listElements[index]->SetSelectedFromTop();
} else if (call == 1) {
call++;
listElements[index]->SetSelectedFromBottom();
}
} else if (listElements[index]->Current()) {
if (call == 0) {
call++;
listElements[index]->SetSelectedFromBottom();
} else if (call == 1) {
call++;
listElements[index]->SetSelectedFromTop();
}
}
}
void cViewList::CheckListAnimation(int index) {
itemCount++;
if (listElements[index])
listElements[index]->StopListAnimation();
}
/******************************************************************
* cViewListDefault
******************************************************************/
@@ -364,6 +381,7 @@ void cViewListDefault::Prepare(int start, int step) {
listDefault[i] = new cLeMenuDefault(*tpl);
listElements[i] = listDefault[i];
listDefault[i]->SetNumber(i);
listDefault[i]->SetOrientation(orientation);
listDefault[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@@ -446,6 +464,7 @@ void cViewListDefault::SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5)
void cViewListDefault::Set(const char *text, int index, bool current, bool selectable) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listDefault[index]->StopScrolling();
listDefault[index]->SetCurrent(current);
@@ -489,6 +508,7 @@ void cViewListMain::Prepare(int start, int step) {
listMain[i] = new cLeMenuMain(*tpl);
listElements[i] = listMain[i];
listMain[i]->SetNumber(i);
listMain[i]->SetOrientation(orientation);
listMain[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@@ -524,6 +544,7 @@ void cViewListMain::Prepare(int start, int step) {
void cViewListMain::Set(const char *text, int index, bool current, bool selectable) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listMain[index]->StopScrolling();
listMain[index]->SetCurrent(current);
@@ -568,6 +589,7 @@ void cViewListSchedules::Prepare(int start, int step) {
listSchedules[i] = new cLeMenuSchedules(*tpl);
listElements[i] = listSchedules[i];
listSchedules[i]->SetNumber(i);
listSchedules[i]->SetOrientation(orientation);
listSchedules[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@@ -604,6 +626,7 @@ void cViewListSchedules::Set(const cEvent *event, int index, bool current, bool
const cChannel *channel, bool withDate, eTimerMatch timerMatch) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listSchedules[index]->StopScrolling();
listSchedules[index]->SetCurrent(current);
@@ -640,6 +663,7 @@ void cViewListTimers::Prepare(int start, int step) {
listTimers[i] = new cLeMenuTimers(*tpl);
listElements[i] = listTimers[i];
listTimers[i]->SetNumber(i);
listTimers[i]->SetOrientation(orientation);
listTimers[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@@ -675,6 +699,7 @@ void cViewListTimers::Prepare(int start, int step) {
void cViewListTimers::Set(const cTimer *timer, int index, bool current, bool selectable) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listTimers[index]->StopScrolling();
listTimers[index]->SetCurrent(current);
@@ -710,6 +735,7 @@ void cViewListChannels::Prepare(int start, int step) {
listChannels[i] = new cLeMenuChannels(*tpl);
listElements[i] = listChannels[i];
listChannels[i]->SetNumber(i);
listChannels[i]->SetOrientation(orientation);
listChannels[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@@ -745,6 +771,7 @@ void cViewListChannels::Prepare(int start, int step) {
void cViewListChannels::Set(const cChannel *channel, int index, bool current, bool selectable, bool withProvider) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listChannels[index]->StopScrolling();
listChannels[index]->SetCurrent(current);
@@ -780,6 +807,7 @@ void cViewListRecordings::Prepare(int start, int step) {
listRecordings[i] = new cLeMenuRecordings(*tpl);
listElements[i] = listRecordings[i];
listRecordings[i]->SetNumber(i);
listRecordings[i]->SetOrientation(orientation);
listRecordings[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@@ -815,6 +843,7 @@ void cViewListRecordings::Prepare(int start, int step) {
void cViewListRecordings::Set(const cRecording *recording, int index, bool current, bool selectable, int level, int total, int New) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listRecordings[index]->StopScrolling();
listRecordings[index]->SetCurrent(current);
@@ -853,6 +882,7 @@ void cViewListPlugin::Prepare(int start, int step) {
listPlugin[i] = new cLeMenuPlugin(*tpl);
listElements[i] = listPlugin[i];
listPlugin[i]->SetNumber(i);
listPlugin[i]->SetOrientation(orientation);
listPlugin[i]->SetPlugId(plugId);
listPlugin[i]->SetPlugMenuId(plugMenuId);
listPlugin[i]->SetTokenContainer();
@@ -893,6 +923,7 @@ void cViewListPlugin::Prepare(int start, int step) {
void cViewListPlugin::Set(skindesignerapi::cTokenContainer *tk, int index, bool current, bool selectable) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listPlugin[index]->StopScrolling();
listPlugin[index]->SetCurrent(current);
@@ -1056,6 +1087,7 @@ void cViewListChannelList::Prepare(int start, int step) {
listChannelList[i] = new cLeChannelList(*tpl);
listElements[i] = listChannelList[i];
listChannelList[i]->SetNumber(i);
listChannelList[i]->SetOrientation(orientation);
listChannelList[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@@ -1080,6 +1112,7 @@ void cViewListChannelList::Prepare(int start, int step) {
void cViewListChannelList::Set(const cChannel *channel, int index, bool current) {
if (index < 0 || index >= numElements)
return;
itemCount++;
if (!current)
listChannelList[index]->StopScrolling();
listChannelList[index]->SetCurrent(current);
@@ -1113,6 +1146,7 @@ void cViewListGroupList::Prepare(int start, int step) {
listGroupList[i] = new cLeGroupList(*tpl);
listElements[i] = listGroupList[i];
listGroupList[i]->SetNumber(i);
listGroupList[i]->SetOrientation(orientation);
listGroupList[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@@ -1137,6 +1171,7 @@ void cViewListGroupList::Prepare(int start, int step) {
void cViewListGroupList::Set(const char *group, int numChannels, int index, bool current) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listGroupList[index]->StopScrolling();
listGroupList[index]->SetCurrent(current);

View File

@@ -16,13 +16,17 @@ protected:
skindesignerapi::cTokenContainer *tokenContainer;
int numElements;
eOrientation orientation;
bool cleared;
int itemCount;
cViewElement *listElement;
cViewElement *currentElement;
cListElement **listElements;
cAnimation *fader;
cAnimation *shifter;
cFader *fader;
cShifter *shifter;
virtual void Prepare(int start, int step) {};
cPoint ShiftStart(cRect &shiftbox);
void SetShiftParameters(int index, int &call);
void CheckListAnimation(int index);
public:
cViewList(void);
virtual ~cViewList(void);
@@ -42,6 +46,7 @@ public:
eOrientation Orientation(void);
void Draw(eMenuCategory menuCat);
void Clear(void);
void ResetItemCount(void) { itemCount = 0; };
virtual void Close(void);
eButtonType Button(void) { return attribs->Button(); };
//Fadable
@@ -52,14 +57,12 @@ public:
//Shiftable
int ShiftTime(void) { return attribs->ShiftTime(); };
int ShiftMode(void) { return attribs->ShiftMode(); };
void ShiftPositions(cPoint *start, cPoint *end);
void SetPosition(cPoint &position, cPoint &reference, bool force = false);
void SetStartShifting(void) { };
void SetEndShifting(void) { };
void RegisterAnimation(void);
void UnregisterAnimation(void);
cRect CoveredArea(void);
void StartAnimation(void);
void Flush(bool animFlush);
void StartAnimation(bool animOut = false);
void Debug(void);
};