diff options
author | louis <louis.braun@gmx.de> | 2016-07-22 15:21:09 +0200 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2016-07-22 15:21:09 +0200 |
commit | a79af20c340c77f066472d59db003f1f721c9fee (patch) | |
tree | 854e24f03023154dd094959f2abc6dfa685a1045 /coreengine | |
parent | 4f3c24df7b82530b28b54db0cb9869a001527624 (diff) | |
download | vdr-plugin-skindesigner-a79af20c340c77f066472d59db003f1f721c9fee.tar.gz vdr-plugin-skindesigner-a79af20c340c77f066472d59db003f1f721c9fee.tar.bz2 |
redesigned animations
Diffstat (limited to 'coreengine')
31 files changed, 1250 insertions, 674 deletions
diff --git a/coreengine/animation.c b/coreengine/animation.c index be9b95f..f21a604 100644 --- a/coreengine/animation.c +++ b/coreengine/animation.c @@ -1,118 +1,61 @@ +#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 cDetacher::Action(void) { + if (!detachable) { + return; + } + if (waitOnWakeup) { + Wait(); + int delay = 50 + detachable->Delay(); + Sleep(delay); + } else { + int delay = detachable->Delay(); + if (delay > 0) + Sleep(delay); + } + + detachable->ParseDetached(); + detachable->RenderDetached(); + if (!doAnimation) + detachable->Flush(); + if (!Running()) return; + if (doAnimation) { + detachable->StartAnimation(); } } -void cAnimation::Sleep(int duration) { - //sleep should wake up itself, so no infinit wait allowed +void cDetacher::Sleep(int duration) { if (duration <= 0) return; do { @@ -121,258 +64,605 @@ void cAnimation::Sleep(int duration) { } while (keepSleeping); } -void cAnimation::Wait(void) { +void cDetacher::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; +/****************************************************************** +* 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) { - scrollTotal = scrollable->ScrollWidth(); + scrollLength = scrollable->ScrollWidth(); } else if (orientation == eOrientation::vertical) { - scrollTotal = scrollable->ScrollHeight(); + scrollLength = scrollable->ScrollHeight(); } - eScrollMode mode = scrollable->ScrollMode(); - bool carriageReturn = (mode == eScrollMode::carriagereturn) ? true : false; - + carriageReturn = (mode == eScrollMode::carriagereturn) ? true : false; + drawPortX = 0.0f; + drawPortY = 0.0f; eScrollSpeed speed = scrollable->ScrollSpeed(); - int frameTime = 30; if (speed == eScrollSpeed::slow) - frameTime = 50; - else if (speed == eScrollSpeed::medium) - frameTime = 30; + scrollDelta = 0.5f; 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); + scrollDelta = 2.0f; + else + scrollDelta = 1.0f; +} - } - - if (!Running()) return; - scrollable->SetDrawPort(drawPortPoint); +void cScroller::Reactivate(void) {} +void cScroller::SetInitial(void) {} - if (!Running()) return; - scrollable->Flush(true); +bool cScroller::Pause(void) { + if (!paused) + return false; + if ((pauseTime + frametime) > delay) { + paused = false; + pauseTime = 0; + return false; + } + pauseTime += frametime; + return true; +} - if (orientation == eOrientation::horizontal && !carriageReturn && (drawPortX == 0)) { +bool cScroller::Overflow(void) { + if (orientation == eOrientation::horizontal) { + if (!carriageReturn && (drawPortX >= 1)) { + drawPortX = 0; scrollDelta *= -1; - doSleep = true; + paused = true; + return 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; +} - int delta = cTimeMs::Now() - now; - if (delta < frameTime) - Sleep(frameTime - delta); +void cScroller::SetFinished(void) { + finished = true; + if (delScrollPix) { + scrollable->StopScrolling(); } } -void cAnimation::Detach(void) { - if (waitOnWakeup) { - Wait(); - int delay = 50 + detachable->Delay(); - Sleep(delay); - } else { - int delay = detachable->Delay(); - if (delay > 0) - Sleep(delay); +bool cScroller::Tick(void) { + if (finished) { + return false; } - //if (!Running()) return; - detachable->ParseDetached(); - //if (!Running()) return; - detachable->RenderDetached(); - //if (!Running()) return; - if (!doAnimation) - detachable->Flush(false); - if (!Running()) return; - if (doAnimation) { - detachable->StartAnimation(); + + 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 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; +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; + transparency += step; } - //wait configured delay if not already done by detacher - if (!fadable->Detached()) { - int delay = fadable->Delay(); - if (delay > 0) - Sleep(delay); + 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); } - 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; + 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; } - if (modeIn) { - transparency -= step; - if (transparency < 0) - transparency = 0; + } else if (mode == eShiftMode::slowedDown) { + if (shiftin) { + if (step <= stepsFast) { + x += stepXFast; + y += stepYFast; + } else { + x += stepXSlow; + y += stepYSlow; + } } else { - transparency += step; - if (transparency > 100) - transparency = 100; + if (step <= stepsFast) { + x -= stepXFast; + y -= stepYFast; + } else { + x -= stepXSlow; + y -= stepYSlow; + } } } } -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; +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; +}; - int frametime = 1000 / FPS; +/****************************************************************** +* cListShifter +******************************************************************/ +cListShifter::cListShifter(cListShiftable *shiftable) { + this->shiftable = shiftable; + shifttime = shiftable->ListShiftTime(); + distance = shiftable->ShiftDistance(); + orientation = shiftable->ShiftOrientation(); int steps = (double)shifttime / (double)frametime; - if (steps < 2) - 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; + 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 { - stepXLinear = (shiftend.X() - shiftstart.X()) / steps; - stepYLinear = (shiftend.Y() - shiftstart.Y()) / steps; + if (fromtop) { + pos.SetY(y+step); + } else { + pos.SetY(y-step); + } } - int stepX = stepXLinear; - int stepY = stepYLinear; +} - cPoint pos; - if (modeIn) - pos = shiftstart; - else - pos = shiftend; +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); +} - //wait configured delay if not already done by detacher - if (!shiftable->Detached()) { - int delay = shiftable->Delay(); - if (delay > 0) - Sleep(delay); +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->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); + 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; } - if ((int)(now - start) > shifttime) { - finished = true; - if ((Running() && modeIn) && pos != shiftend) { - shiftable->SetPosition(shiftend, shiftend); - shiftable->Flush(true); + } + 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); + } while (found); + animLock.Unlock(); +} + +/***************************************************************************************** +* 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 { - pos.Set(pos.X() - stepX, pos.Y() - stepY); + Sleep(start); } } - if (!finished) { - shiftable->SetPosition(shiftend, shiftend); +} + +/***************************************************************************************** +* 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; + } } - shiftable->SetEndShifting(); -} - -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; + 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); } } diff --git a/coreengine/animation.h b/coreengine/animation.h index 8679f59..078b81e 100644 --- a/coreengine/animation.h +++ b/coreengine/animation.h @@ -4,11 +4,64 @@ #include <vdr/skins.h> #include <vdr/thread.h> #include "definitions.h" +#include "osdwrapper.h" -#define FPS 50 +/****************************************************************** +* 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; }; +}; /****************************************************************** -* cScrollable +* 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
\ No newline at end of file diff --git a/coreengine/area.c b/coreengine/area.c index fe96ca2..d90fadb 100644 --- a/coreengine/area.c +++ b/coreengine/area.c @@ -252,6 +252,17 @@ void cArea::Clear(bool forceClearBackground) { } 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); diff --git a/coreengine/area.h b/coreengine/area.h index f8d548d..a99666c 100644 --- a/coreengine/area.h +++ b/coreengine/area.h @@ -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); diff --git a/coreengine/attributes.c b/coreengine/attributes.c index b0d0dba..b85034b 100644 --- a/coreengine/attributes.c +++ b/coreengine/attributes.c @@ -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")); diff --git a/coreengine/attributes.h b/coreengine/attributes.h index c0a7402..5901931 100644 --- a/coreengine/attributes.h +++ b/coreengine/attributes.h @@ -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; }; diff --git a/coreengine/definitions.h b/coreengine/definitions.h index e2a8e4d..c5be02c 100644 --- a/coreengine/definitions.h +++ b/coreengine/definitions.h @@ -1677,6 +1677,7 @@ enum class eAreaAttribs { scrollspeed, delay, background, + indicator, name, scrollheight, count diff --git a/coreengine/listelements.c b/coreengine/listelements.c index 8f7c2ee..ec8cf3a 100644 --- a/coreengine/listelements.c +++ b/coreengine/listelements.c @@ -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 ******************************************************************/ diff --git a/coreengine/listelements.h b/coreengine/listelements.h index a63fa4d..d76bb2e 100644 --- a/coreengine/listelements.h +++ b/coreengine/listelements.h @@ -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); }; diff --git a/coreengine/osdwrapper.c b/coreengine/osdwrapper.c index 0bd1e01..07c0cf6 100644 --- a/coreengine/osdwrapper.c +++ b/coreengine/osdwrapper.c @@ -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(); } } diff --git a/coreengine/osdwrapper.h b/coreengine/osdwrapper.h index 47bb20f..252479b 100644 --- a/coreengine/osdwrapper.h +++ b/coreengine/osdwrapper.h @@ -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); }; diff --git a/coreengine/view.c b/coreengine/view.c index f9db80d..95d88a4 100644 --- a/coreengine/view.c +++ b/coreengine/view.c @@ -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) { diff --git a/coreengine/view.h b/coreengine/view.h index a27ed7a..f6cec00 100644 --- a/coreengine/view.h +++ b/coreengine/view.h @@ -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 diff --git a/coreengine/viewdisplaychannel.c b/coreengine/viewdisplaychannel.c index 0702252..284dbcc 100644 --- a/coreengine/viewdisplaychannel.c +++ b/coreengine/viewdisplaychannel.c @@ -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(); } diff --git a/coreengine/viewdisplaychannel.h b/coreengine/viewdisplaychannel.h index 497d327..16c5393 100644 --- a/coreengine/viewdisplaychannel.h +++ b/coreengine/viewdisplaychannel.h @@ -71,7 +71,7 @@ public: void SetChannelHint(const cChannel *channel); #endif void Close(void); - void Flush(bool animFlush); + void Flush(void); }; #endif //__VIEWDISPLAYCHANNEL_H
\ No newline at end of file diff --git a/coreengine/viewdisplaymenu.c b/coreengine/viewdisplaymenu.c index b1cc0cc..88ad756 100644 --- a/coreengine/viewdisplaymenu.c +++ b/coreengine/viewdisplaymenu.c @@ -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(); } } diff --git a/coreengine/viewdisplaymenu.h b/coreengine/viewdisplaymenu.h index d2588ce..b50bdb0 100644 --- a/coreengine/viewdisplaymenu.h +++ b/coreengine/viewdisplaymenu.h @@ -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); }; diff --git a/coreengine/viewdisplaymessage.c b/coreengine/viewdisplaymessage.c index 12e0618..0fb78af 100644 --- a/coreengine/viewdisplaymessage.c +++ b/coreengine/viewdisplaymessage.c @@ -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(); } diff --git a/coreengine/viewdisplaymessage.h b/coreengine/viewdisplaymessage.h index 4ee36e5..83ee7b0 100644 --- a/coreengine/viewdisplaymessage.h +++ b/coreengine/viewdisplaymessage.h @@ -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
\ No newline at end of file diff --git a/coreengine/viewdisplayplugin.c b/coreengine/viewdisplayplugin.c index 8830534..5808025 100644 --- a/coreengine/viewdisplayplugin.c +++ b/coreengine/viewdisplayplugin.c @@ -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) { diff --git a/coreengine/viewdisplayplugin.h b/coreengine/viewdisplayplugin.h index 7aac3d7..85ea4e6 100644 --- a/coreengine/viewdisplayplugin.h +++ b/coreengine/viewdisplayplugin.h @@ -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); }; diff --git a/coreengine/viewdisplayreplay.c b/coreengine/viewdisplayreplay.c index 8a61669..28373b6 100644 --- a/coreengine/viewdisplayreplay.c +++ b/coreengine/viewdisplayreplay.c @@ -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(); -}
\ No newline at end of file +} diff --git a/coreengine/viewdisplayreplay.h b/coreengine/viewdisplayreplay.h index fdc9141..162d63e 100644 --- a/coreengine/viewdisplayreplay.h +++ b/coreengine/viewdisplayreplay.h @@ -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
\ No newline at end of file diff --git a/coreengine/viewdisplaytracks.c b/coreengine/viewdisplaytracks.c index 067d2d6..8c613d8 100644 --- a/coreengine/viewdisplaytracks.c +++ b/coreengine/viewdisplaytracks.c @@ -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(); } diff --git a/coreengine/viewdisplaytracks.h b/coreengine/viewdisplaytracks.h index 36f53f8..e56fa82 100644 --- a/coreengine/viewdisplaytracks.h +++ b/coreengine/viewdisplaytracks.h @@ -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
\ No newline at end of file diff --git a/coreengine/viewdisplayvolume.c b/coreengine/viewdisplayvolume.c index a63febc..d3f1454 100644 --- a/coreengine/viewdisplayvolume.c +++ b/coreengine/viewdisplayvolume.c @@ -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(); } diff --git a/coreengine/viewdisplayvolume.h b/coreengine/viewdisplayvolume.h index b89fdbc..6fa7f17 100644 --- a/coreengine/viewdisplayvolume.h +++ b/coreengine/viewdisplayvolume.h @@ -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
\ No newline at end of file diff --git a/coreengine/viewelement.c b/coreengine/viewelement.c index 89fb69d..811aad8 100644 --- a/coreengine/viewelement.c +++ b/coreengine/viewelement.c @@ -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); }
\ No newline at end of file diff --git a/coreengine/viewelement.h b/coreengine/viewelement.h index fa7c4cc..644b6a8 100644 --- a/coreengine/viewelement.h +++ b/coreengine/viewelement.h @@ -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); diff --git a/coreengine/viewlist.c b/coreengine/viewlist.c index a10bb9a..5ef52c8 100644 --- a/coreengine/viewlist.c +++ b/coreengine/viewlist.c @@ -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); diff --git a/coreengine/viewlist.h b/coreengine/viewlist.h index 8e968c8..150ed65 100644 --- a/coreengine/viewlist.h +++ b/coreengine/viewlist.h @@ -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); }; |