From ccbd03f37612ea6e4fc45fa5067bec15fe67a291 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Fri, 31 Jan 2025 09:12:53 +0100 Subject: [PATCH] CtrlLib: Additional Animate functions --- uppsrc/CtrlCore/src.tpp/Animation_en-us.tpp | 24 +++++++++++++- uppsrc/CtrlLib/CtrlUtil.cpp | 36 +++++++-------------- uppsrc/CtrlLib/CtrlUtil.h | 16 +++++++++ 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/uppsrc/CtrlCore/src.tpp/Animation_en-us.tpp b/uppsrc/CtrlCore/src.tpp/Animation_en-us.tpp index 3d0e8d800..8ab7c25a2 100644 --- a/uppsrc/CtrlCore/src.tpp/Animation_en-us.tpp +++ b/uppsrc/CtrlCore/src.tpp/Animation_en-us.tpp @@ -30,6 +30,13 @@ value will cause the the [%- ctrl ]to jump directly to the target rectangle without any animation.&] [s3; &] [s4; &] +[s5;:Upp`:`:Animate`(Event`,int`): [@(0.0.255) void] [* Animate](Event<[@(0.0.255) double]> + [*@3 update], [@(0.0.255) int] [*@3 duration] [@(0.0.255) `=] [@3 100])&] +[s2;%% Performs GUI animation, repeatedly calling [%-*@3 update] with +increasing numbers from the interval 0..1 for [%-*@3 duration] +milliseconds.&] +[s3; &] +[s4; &] [s5;:Upp`:`:Animate`(Vector`&`,const Vector`&`,int`): [@(0.0.255) void] [* Animate](Vector>[@(0.0.255) `&] [*@3 ctrls], [@(0.0.255) const] Vector[@(0.0.255) `&] [*@3 targets], [@(0.0.255) int] [*@3 duration] @@ -38,7 +45,22 @@ Vector[@(0.0.255) `&] [*@3 targets], [@(0.0.255) int] [*@3 duration] current positions to the target positions specified by the [%-*@3 targets] parameter, over a given [%-*@3 duration]. The default duration is 100 miliseconds. The number of ctrls must match the number -of the target rectangles. Otherwise the function will silently +of the target rectangles otherwise the function will silently return without modifying anything.&] [s3; &] +[s4; &] +[s5;:Upp`:`:Animate`(Vector`&`,const Vector`&`,Event`,int`): [@(0.0.255) template] +<[@(0.0.255) class] T>&] +[s5;:Upp`:`:Animate`(Vector`&`,const Vector`&`,Event`,int`): [@(0.0.255) void] +[* Animate](Vector[@(0.0.255) `&] [*@3 data], [@(0.0.255) const] Vector[@(0.0.255) `& +] [*@3 targets], Event<> [*@3 update], [@(0.0.255) int] [*@3 duration] +[@(0.0.255) `=] [@3 100])&] +[s2;%% Animates the transition of multiple [%-*@3 data] values from +their current positions to the target positions specified by +the [%-*@3 targets] parameter, over a given [%-*@3 duration]. The +default duration is 100 miliseconds. The number of [%-*@3 data] +values must match the number of the [%-*@3 targets ]values otherwise +the function will silently return without modifying anything. +After each animation step Animate calls [%-*@3 update].&] +[s3; &] [s0;%% ]] \ No newline at end of file diff --git a/uppsrc/CtrlLib/CtrlUtil.cpp b/uppsrc/CtrlLib/CtrlUtil.cpp index acb14d8e5..ca91b4dd2 100644 --- a/uppsrc/CtrlLib/CtrlUtil.cpp +++ b/uppsrc/CtrlLib/CtrlUtil.cpp @@ -4,8 +4,6 @@ namespace Upp { #define LLOG(x) // RLOG(x) -// #define SLOWANIMATION - #define IMAGECLASS CtrlImg #define IMAGEFILE #include @@ -17,9 +15,6 @@ void Animate(Ctrl& c, const Rect& target, int type) Rect r0 = c.GetRect(); dword time0 = msecs(); int anitime = 150; -#ifdef SLOWANIMATION - anitime = 1500; -#endif if(type) for(;;) { int t = int(msecs() - time0); @@ -48,12 +43,8 @@ void Animate(Ctrl& c, const Rect& target, int type) c.SetAlpha((byte)(255 * t / anitime)); else break; - c.Sync(); - c.ProcessEvents(); - Sleep(0); -#ifdef SLOWANIMATION - Sleep(100); -#endif + Ctrl::ProcessEvents(); + Ctrl::GuiSleep(0); } c.SetRect(target); c.SetAlpha(255); @@ -64,29 +55,24 @@ void Animate(Ctrl& c, int x, int y, int cx, int cy, int type) Animate(c, RectC(x, y, cx, cy), type); } -template -void Animate(Vector& data, const Vector& targets, Event<> update, int duration) +void Animate(Event update, int duration) { - if(data.GetCount() != targets.GetCount() || duration < 1) + if(duration < 1) return; - int start = msecs(), elapsed = 0; - - Vector src = clone(data); - - while(elapsed <= duration) { + int start = msecs(); + for(;;) { int elapsed = msecs() - start; + if(elapsed > duration) + break; double t = min(1.0, (double) elapsed / (double) duration); t = t * t * (3 - 2 * t); // Ease-in-out (smoother movement). - for(int i = 0; i < data.GetCount(); i++) - data[i] = Lerp(src[i], targets[i], t); - update(); + update(t); Ctrl::ProcessEvents(); Ctrl::GuiSleep(0); } - data = clone(targets); - update(); -} + update(1); + } void Animate(Vector>& ctrls, const Vector& targets, int duration) { diff --git a/uppsrc/CtrlLib/CtrlUtil.h b/uppsrc/CtrlLib/CtrlUtil.h index 0709ab13e..cea155ae4 100644 --- a/uppsrc/CtrlLib/CtrlUtil.h +++ b/uppsrc/CtrlLib/CtrlUtil.h @@ -1,7 +1,23 @@ void Animate(Ctrl& c, const Rect& target, int type = -1); void Animate(Ctrl& c, int x, int y, int cx, int cy, int type = -1); +void Animate(Event update, int duration = 100); void Animate(Vector>& ctrls, const Vector& targets, int duration = 100); +template +void Animate(Vector& data, const Vector& targets, Event<> update, int duration = 100) +{ + if(data.GetCount() != targets.GetCount()) + return; + + Vector src = clone(data); + + Animate([&](double t) { + for(int i = 0; i < data.GetCount(); i++) + data[i] = Lerp(src[i], targets[i], t); + update(); + }, duration); +} + bool CtrlLibDisplayError(const Value& ev); bool EditText(String& s, const char *title, const char *label, int (*filter)(int), int maxlen = 0);