diff --git a/code/nel/include/nel/gui/interface_anim.h b/code/nel/include/nel/gui/interface_anim.h
new file mode 100644
index 000000000..660005a3e
--- /dev/null
+++ b/code/nel/include/nel/gui/interface_anim.h
@@ -0,0 +1,135 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+
+#ifndef RZ_INTERFACE_ANIM_H
+#define RZ_INTERFACE_ANIM_H
+
+#include "nel/gui/interface_property.h"
+#include "nel/gui/interface_group.h"
+#include "nel/gui/interface_link.h"
+#include "nel/3d/animation_time.h"
+#include "nel/3d/u_track.h"
+
+namespace NLGUI
+{
+
+ /**
+ * class managing an animation track
+ * \author Matthieu 'TrapII' Besson
+ * \author Nevrax France
+ * \date 2003
+ */
+ class CInterfaceTrack
+ {
+
+ public:
+
+ CInterfaceTrack();
+ ~CInterfaceTrack();
+
+ virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup);
+
+ void update (double currentTime);
+
+ bool isDynamic () { return _Dynamic; }
+
+ void eval(); // Evaluate dynamic keys
+
+ private:
+
+ enum ETrackType
+ {
+ Track_Linear,
+ Track_TCB,
+ Track_Bezier
+ };
+
+ struct SDynKey
+ {
+ std::string Time;
+ std::string Value;
+ std::string InTan;
+ std::string OutTan;
+ std::string Step;
+ std::string Tension;
+ std::string Continuity;
+ std::string Bias;
+ std::string EaseTo;
+ std::string EaseFrom;
+ };
+
+ bool _Dynamic;
+ std::vector _DynKeys;
+
+ ETrackType _Type;
+ NL3D::UTrackKeyframer *_TrackKeyFramer;
+ std::vector _Targets;
+ };
+
+ /**
+ * class managing an animation of the interface
+ * \author Matthieu 'TrapII' Besson
+ * \author Nevrax France
+ * \date 2003
+ */
+ class CInterfaceAnim
+ {
+
+ public:
+
+ CInterfaceAnim();
+ ~CInterfaceAnim();
+
+ virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup);
+
+ void update();
+ void start();
+ void stop();
+
+ bool isFinished() { return _Finished; }
+ bool isDisableButtons() { return _DisableButtons; }
+
+ protected:
+
+ CInterfaceGroup *_Parent;
+
+ // Parsed properties
+ double _Duration;
+ bool _DisableButtons;
+
+ std::string _AHOnFinish;
+ std::string _AHOnFinishParams;
+
+ std::string _Id;
+
+ std::vector _Tracks;
+
+ // Current anim
+ double _CurrentTime;
+ bool _Finished;
+ bool _AnimHasToBeStopped;
+
+ };
+
+}
+
+#endif // NL_INTERFACE_ANIM_H
+
+/* End of interface_anim.h */
+
+
diff --git a/code/nel/src/gui/interface_anim.cpp b/code/nel/src/gui/interface_anim.cpp
new file mode 100644
index 000000000..4ca996731
--- /dev/null
+++ b/code/nel/src/gui/interface_anim.cpp
@@ -0,0 +1,647 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#include "nel/gui/interface_anim.h"
+#include "nel/gui/widget_manager.h"
+#include "nel/gui/interface_expr.h"
+#include "nel/misc/xml_auto_ptr.h"
+#include "nel/gui/action_handler.h"
+
+// ----------------------------------------------------------------------------
+using namespace std;
+using namespace NL3D;
+using namespace NLMISC;
+
+namespace NLGUI
+{
+
+ // ----------------------------------------------------------------------------
+ // CInterfaceTrack
+ // ----------------------------------------------------------------------------
+ CInterfaceTrack::CInterfaceTrack()
+ {
+ _Type = Track_Linear;
+ _TrackKeyFramer = NULL;
+ _Dynamic = false;
+ }
+
+ // ----------------------------------------------------------------------------
+ CInterfaceTrack::~CInterfaceTrack()
+ {
+ delete _TrackKeyFramer;
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CInterfaceTrack::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
+ {
+ CXMLAutoPtr ptr;
+
+ ptr = xmlGetProp (cur, (xmlChar*)"dynamic");
+ if (ptr) _Dynamic = CInterfaceElement::convertBool (ptr);
+
+ ptr = xmlGetProp (cur, (xmlChar*)"type");
+ string sTmp = ptr;
+ sTmp = strlwr(sTmp);
+ if (sTmp == "linear")
+ _Type = Track_Linear;
+ else if (sTmp == "bezier")
+ _Type = Track_Bezier;
+ else if (sTmp == "tcb")
+ _Type = Track_TCB;
+ else
+ nlwarning ("track unknown type : %s, setting linear by default", (const char*)ptr);
+
+ ptr = xmlGetProp (cur, (xmlChar*)"target");
+ if (!ptr)
+ {
+ nlwarning ("no target for track");
+ return false;
+ }
+
+ //
+ if (!CInterfaceLink::splitLinkTargets (ptr, parentGroup, _Targets))
+ {
+ nlwarning ("no target for track");
+ return false;
+ }
+
+ // Initialize the track
+ switch(_Type)
+ {
+ case Track_Linear: _TrackKeyFramer = UTrackKeyframer::createLinearFloatTrack(); break;
+ case Track_TCB: _TrackKeyFramer = UTrackKeyframer::createTCBFloatTrack(); break;
+ case Track_Bezier: _TrackKeyFramer = UTrackKeyframer::createBezierFloatTrack(); break;
+ default: nlstop; break;
+ }
+
+ cur = cur->children;
+ bool ok = true;
+
+ if (_Dynamic)
+ {
+ while (cur)
+ {
+ // Check that this is a key node
+ if ( stricmp((char*)cur->name,"key") != 0 )
+ {
+ cur = cur->next;
+ continue;
+ }
+
+ // Read time and value the 2 main key attributes
+ CXMLAutoPtr time, value;
+ time = xmlGetProp (cur, (xmlChar*)"time");
+ value = xmlGetProp (cur, (xmlChar*)"value");
+ if (!time || !value)
+ {
+ nlwarning("track key with no time or no value");
+ ok = false;
+ cur = cur->next;
+ continue;
+ }
+
+ SDynKey k;
+ k.Value = (const char*)value;
+ k.Time = (const char*)time;
+ if (isdigit(k.Time[0]) || (k.Time[0] == '-'))
+ {
+ double dTime;
+ fromString(k.Time, dTime);
+ k.Time = toString(dTime * CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionMulCoefAnim).getValFloat());
+ }
+
+ // Depending on the type of the track read extra values
+ switch(_Type)
+ {
+ case Track_Linear:
+ break;
+
+ case Track_Bezier:
+ {
+ CXMLAutoPtr inTan, outTan, step;
+ inTan = xmlGetProp (cur, (xmlChar*)"intan");
+ outTan = xmlGetProp (cur, (xmlChar*)"outtan");
+ step = xmlGetProp (cur, (xmlChar*)"step");
+
+ if (inTan) k.InTan = (const char*)inTan;
+ if (outTan) k.OutTan = (const char*)outTan;
+ if (step) k.Step = (const char*)step;
+ }
+ break;
+
+ case Track_TCB:
+ {
+ CXMLAutoPtr tension, continuity, bias, easeto, easefrom;
+ tension = xmlGetProp (cur, (xmlChar*)"tension");
+ continuity = xmlGetProp (cur, (xmlChar*)"continuity");
+ bias = xmlGetProp (cur, (xmlChar*)"bias");
+ easeto = xmlGetProp (cur, (xmlChar*)"easeto");
+ easefrom = xmlGetProp (cur, (xmlChar*)"easefrom");
+
+ if (tension) k.Tension = (const char*)tension;
+ if (continuity) k.Continuity = (const char*)continuity;
+ if (bias) k.Bias = (const char*)bias;
+ if (easeto) k.EaseTo = (const char*)easeto;
+ if (easefrom) k.EaseFrom = (const char*)easefrom;
+ }
+ break;
+ default: nlstop; break;
+ }
+ _DynKeys.push_back(k);
+
+ cur = cur->next;
+ }
+ }
+ else // Static parsing
+ {
+ while (cur)
+ {
+ // Check that this is a key node
+ if ( stricmp((char*)cur->name,"key") != 0 )
+ {
+ cur = cur->next;
+ continue;
+ }
+
+ // Read time and value the 2 main key attributes
+ CXMLAutoPtr time, value;
+ time = xmlGetProp (cur, (xmlChar*)"time");
+ value = xmlGetProp (cur, (xmlChar*)"value");
+ if (!time || !value)
+ {
+ nlwarning("track key with no time or no value");
+ ok = false;
+ cur = cur->next;
+ continue;
+ }
+
+ float fAnimTime;
+ fromString((const char*)time, fAnimTime);
+ TAnimationTime animTime = fAnimTime * CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionMulCoefAnim).getValFloat();
+ double animValue;
+ fromString(value, animValue);
+
+ // Depending on the type of the track add the key
+ switch(_Type)
+ {
+ case Track_Linear:
+ {
+ UTrackKeyframer::UKeyLinearFloat k;
+ k.Time = animTime;
+ k.Value = (float)animValue;
+ _TrackKeyFramer->addLinearFloatKey (k);
+ }
+ break;
+
+ case Track_Bezier:
+ {
+ UTrackKeyframer::UKeyBezierFloat k;
+ k.Time = animTime;
+ k.Value = (float)animValue;
+
+ // Read extra values
+ CXMLAutoPtr inTan, outTan, step;
+ inTan = xmlGetProp (cur, (xmlChar*)"intan");
+ outTan = xmlGetProp (cur, (xmlChar*)"outtan");
+ step = xmlGetProp (cur, (xmlChar*)"step");
+
+ k.TanIn = 0.0f;
+ k.TanOut = 0.0f;
+ k.Step = false;
+
+ if (inTan) fromString((const char*)inTan, k.TanIn);
+ if (outTan) fromString((const char*)outTan, k.TanOut);
+ if (step) k.Step = CInterfaceElement::convertBool(step);
+
+ _TrackKeyFramer->addBezierFloatKey (k);
+ }
+ break;
+
+ case Track_TCB:
+ {
+ UTrackKeyframer::UKeyTCBFloat k;
+ k.Time = animTime;
+ k.Value = (float)animValue;
+
+ // Read extra values
+ CXMLAutoPtr tension, continuity, bias, easeto, easefrom;
+ tension = xmlGetProp (cur, (xmlChar*)"tension");
+ continuity = xmlGetProp (cur, (xmlChar*)"continuity");
+ bias = xmlGetProp (cur, (xmlChar*)"bias");
+ easeto = xmlGetProp (cur, (xmlChar*)"easeto");
+ easefrom = xmlGetProp (cur, (xmlChar*)"easefrom");
+
+ k.Tension = 0.0f;
+ k.Continuity = 0.0f;
+ k.Bias = 0.0f;
+ k.EaseTo = 0.0f;
+ k.EaseFrom = 0.0f;
+
+ if (tension) fromString((const char*)tension, k.Tension);
+ if (continuity) fromString((const char*)continuity, k.Continuity);
+ if (bias) fromString((const char*)bias, k.Bias);
+ if (easeto) fromString((const char*)easeto, k.EaseTo);
+ if (easefrom) fromString((const char*)easefrom, k.EaseFrom);
+
+ _TrackKeyFramer->addTCBFloatKey (k);
+ }
+ break;
+ default: nlstop; break;
+ }
+ cur = cur->next;
+ }
+ }
+ return true;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CInterfaceTrack::update (double currentTime)
+ {
+ float currentValue;
+ UTrack *pTrack = dynamic_cast(_TrackKeyFramer);
+ if (pTrack == NULL) return;
+ pTrack->interpolate((TAnimationTime)currentTime, currentValue);
+
+ // Update the targets
+ CInterfaceExprValue expr;
+ expr.setDouble(currentValue);
+ for (uint i = 0; i < _Targets.size(); ++i)
+ _Targets[i].affect(expr);
+ }
+
+ // ----------------------------------------------------------------------------
+ void CInterfaceTrack::eval()
+ {
+ if (!_Dynamic) return;
+
+ if (_TrackKeyFramer != NULL)
+ delete _TrackKeyFramer;
+
+ switch(_Type)
+ {
+ case Track_Linear:
+ {
+ _TrackKeyFramer = UTrackKeyframer::createLinearFloatTrack();
+ for (uint i = 0; i < _DynKeys.size(); ++i)
+ {
+ SDynKey &rKey = _DynKeys[i];
+ UTrackKeyframer::UKeyLinearFloat k;
+ CInterfaceExprValue res;
+ if (!rKey.Time.empty() && CInterfaceExpr::eval(rKey.Time, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert Time to double");
+ else
+ k.Time = (TAnimationTime)res.getDouble();
+ }
+ else
+ {
+ k.Time = 0;
+ }
+
+ if (!rKey.Value.empty() && CInterfaceExpr::eval(rKey.Value, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert Value to double");
+ else
+ k.Value = (float)res.getDouble();
+ }
+ else
+ {
+ k.Value = 0;
+ }
+
+ _TrackKeyFramer->addLinearFloatKey (k);
+ }
+ }
+ break;
+
+ case Track_TCB:
+ {
+ _TrackKeyFramer = UTrackKeyframer::createTCBFloatTrack();
+ for (uint i = 0; i < _DynKeys.size(); ++i)
+ {
+ SDynKey &rKey = _DynKeys[i];
+ UTrackKeyframer::UKeyTCBFloat k;
+ CInterfaceExprValue res;
+ if (!rKey.Time.empty() && CInterfaceExpr::eval(rKey.Time, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert Time to double");
+ else
+ k.Time = (TAnimationTime)res.getDouble();
+ }
+ else
+ {
+ k.Time = 0;
+ }
+
+ if (!rKey.Value.empty() && CInterfaceExpr::eval(rKey.Value, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert Value to double");
+ else
+ k.Value = (float)res.getDouble();
+ }
+ else
+ {
+ k.Value = 0;
+ }
+
+ if (!rKey.Tension.empty() && CInterfaceExpr::eval(rKey.Tension, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert Tension to double");
+ else
+ k.Tension = (float)res.getDouble();
+ }
+ else
+ {
+ k.Tension = 0;
+ }
+
+ if (!rKey.Continuity.empty() && CInterfaceExpr::eval(rKey.Continuity, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert Continuity to double");
+ else
+ k.Continuity = (float)res.getDouble();
+ }
+ else
+ {
+ k.Continuity = 0;
+ }
+
+ if (!rKey.Bias.empty() && CInterfaceExpr::eval(rKey.Bias, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert Bias to double");
+ else
+ k.Bias = (float)res.getDouble();
+ }
+ else
+ {
+ k.Bias = 0;
+ }
+
+ if (!rKey.EaseTo.empty() && CInterfaceExpr::eval(rKey.EaseTo, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert EaseTo to double");
+ else
+ k.EaseTo = (float)res.getDouble();
+ }
+ else
+ {
+ k.EaseTo = 0;
+ }
+
+ if (!rKey.EaseFrom.empty() && CInterfaceExpr::eval(rKey.EaseFrom, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert EaseFrom to double");
+ else
+ k.EaseFrom = (float)res.getDouble();
+ }
+ else
+ {
+ k.EaseFrom = 0;
+ }
+
+ _TrackKeyFramer->addTCBFloatKey (k);
+ }
+ }
+ break;
+
+ case Track_Bezier:
+ {
+ _TrackKeyFramer = UTrackKeyframer::createBezierFloatTrack(); break;
+ for (uint i = 0; i < _DynKeys.size(); ++i)
+ {
+ SDynKey &rKey = _DynKeys[i];
+ UTrackKeyframer::UKeyBezierFloat k;
+ CInterfaceExprValue res;
+ if (!rKey.Time.empty() && CInterfaceExpr::eval(rKey.Time, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert Time to double");
+ else
+ k.Time = (TAnimationTime)res.getDouble();
+ }
+ else
+ {
+ k.Time = 0;
+ }
+
+ if (!rKey.Value.empty() && CInterfaceExpr::eval(rKey.Value, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert Value to double");
+ else
+ k.Value = (float)res.getDouble();
+ }
+ else
+ {
+ k.Value = 0;
+ }
+
+ if (!rKey.InTan.empty() && CInterfaceExpr::eval(rKey.InTan, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert TanIn to double");
+ else
+ k.TanIn = (float)res.getDouble();
+ }
+ else
+ {
+ k.TanIn = 0;
+ }
+
+ if (!rKey.OutTan.empty() && CInterfaceExpr::eval(rKey.OutTan, res))
+ {
+ if (!res.toDouble())
+ nlwarning ("cannot convert TanOut to double");
+ else
+ k.TanOut = (float)res.getDouble();
+ }
+ else
+ {
+ k.TanOut = 0;
+ }
+
+ if (!rKey.Step.empty() && CInterfaceExpr::eval(rKey.Step, res))
+ {
+ if (!res.toBool())
+ nlwarning ("cannot convert Step to bool");
+ else
+ k.Step = res.getBool();
+ }
+ else
+ {
+ k.Step = false;
+ }
+
+ _TrackKeyFramer->addBezierFloatKey (k);
+ }
+ }
+ default: nlstop; break;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------
+ // CInterfaceAnim
+ // ----------------------------------------------------------------------------
+
+ // ----------------------------------------------------------------------------
+ CInterfaceAnim::CInterfaceAnim()
+ {
+ _CurrentTime = 0;
+ _Finished = true;
+ _Duration = 0;
+ _DisableButtons = true;
+ _AnimHasToBeStopped = false;
+ _Parent = NULL;
+ }
+
+ // ----------------------------------------------------------------------------
+ CInterfaceAnim::~CInterfaceAnim()
+ {
+ for (uint i = 0; i < _Tracks.size(); ++i)
+ delete _Tracks[i];
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CInterfaceAnim::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
+ {
+ CXMLAutoPtr ptr;
+
+ ptr = xmlGetProp (cur, (xmlChar*)"id");
+ _Id = (const char*)ptr;
+
+ ptr = xmlGetProp (cur, (xmlChar*)"duration");
+ if (!ptr)
+ {
+ nlwarning("anim with no duration");
+ return false;
+ }
+ fromString((const char*)ptr, _Duration);
+ if (_Duration == 0)
+ _Duration = 1.0;
+ _Duration *= CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionMulCoefAnim).getValFloat();
+
+ ptr = xmlGetProp (cur, (xmlChar*)"disable_buttons");
+ if (ptr)
+ _DisableButtons = CInterfaceElement::convertBool(ptr);
+
+ ptr = (char*) xmlGetProp( cur, (xmlChar*)"on_finish" );
+ if (ptr) _AHOnFinish = (const char *) ptr;
+ ptr = (char*) xmlGetProp( cur, (xmlChar*)"on_finish_params" );
+ if (ptr) _AHOnFinishParams = (const char *) ptr;
+
+ cur = cur->children;
+
+ // bool ok = true;
+ while (cur)
+ {
+ // Check that this is a key node
+ if ( stricmp((char*)cur->name,"track") != 0 )
+ {
+ cur = cur->next;
+ continue;
+ }
+
+ CInterfaceTrack *pTrack = new CInterfaceTrack;
+ if (!pTrack->parse(cur,parentGroup))
+ {
+ delete pTrack;
+ nlwarning("track not added to anim");
+ }
+ else
+ {
+ _Tracks.push_back(pTrack);
+ }
+ cur = cur->next;
+ }
+
+ _Parent = parentGroup;
+
+ return true;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CInterfaceAnim::update()
+ {
+ if ((_Duration == 0) || (_Finished))
+ return;
+
+ const CWidgetManager::SInterfaceTimes × = CWidgetManager::getInstance()->getInterfaceTimes();
+
+ // Delta time limiter
+ if ( ( times.frameDiffMs / 1000.0f ) > 0.1)
+ _CurrentTime += 0.1;
+ else
+ _CurrentTime += ( times.frameDiffMs / 1000.0f );
+
+ // Stop the anim if we have to
+ if (_AnimHasToBeStopped)
+ {
+ stop();
+ return;
+ }
+
+ // Do this here to let it play the last frame of the animation
+ if (_CurrentTime >= _Duration)
+ {
+ _CurrentTime = _Duration;
+ _AnimHasToBeStopped = true;
+ }
+
+ // Update tracks
+ for (uint i = 0; i < _Tracks.size(); ++i)
+ {
+ CInterfaceTrack *pTrack = _Tracks[i];
+ pTrack->update (_CurrentTime);
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CInterfaceAnim::start()
+ {
+ _CurrentTime = 0.0f;
+ _Finished = false;
+ _AnimHasToBeStopped = false;
+
+ // Look if there are some dynamic tracks
+ for (uint i = 0; i < _Tracks.size(); ++i)
+ if (_Tracks[i]->isDynamic())
+ _Tracks[i]->eval();
+
+ // Play the first frame
+ update();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CInterfaceAnim::stop()
+ {
+ _Finished = true;
+
+ if (!_AHOnFinish.empty())
+ CAHManager::getInstance()->runActionHandler(_AHOnFinish, _Parent, _AHOnFinishParams);
+ }
+
+}
+
diff --git a/code/ryzom/client/src/interface_v3/interface_anim.cpp b/code/ryzom/client/src/interface_v3/interface_anim.cpp
deleted file mode 100644
index 4f9654b62..000000000
--- a/code/ryzom/client/src/interface_v3/interface_anim.cpp
+++ /dev/null
@@ -1,643 +0,0 @@
-// Ryzom - MMORPG Framework
-// Copyright (C) 2010 Winch Gate Property Limited
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-#include "interface_anim.h"
-#include "nel/gui/widget_manager.h"
-#include "nel/gui/interface_expr.h"
-#include "nel/misc/xml_auto_ptr.h"
-#include "nel/gui/action_handler.h"
-
-// ----------------------------------------------------------------------------
-using namespace std;
-using namespace NL3D;
-using namespace NLMISC;
-
-// ----------------------------------------------------------------------------
-// CInterfaceTrack
-// ----------------------------------------------------------------------------
-CInterfaceTrack::CInterfaceTrack()
-{
- _Type = Track_Linear;
- _TrackKeyFramer = NULL;
- _Dynamic = false;
-}
-
-// ----------------------------------------------------------------------------
-CInterfaceTrack::~CInterfaceTrack()
-{
- delete _TrackKeyFramer;
-}
-
-// ----------------------------------------------------------------------------
-bool CInterfaceTrack::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
-{
- CXMLAutoPtr ptr;
-
- ptr = xmlGetProp (cur, (xmlChar*)"dynamic");
- if (ptr) _Dynamic = CInterfaceElement::convertBool (ptr);
-
- ptr = xmlGetProp (cur, (xmlChar*)"type");
- string sTmp = ptr;
- sTmp = strlwr(sTmp);
- if (sTmp == "linear")
- _Type = Track_Linear;
- else if (sTmp == "bezier")
- _Type = Track_Bezier;
- else if (sTmp == "tcb")
- _Type = Track_TCB;
- else
- nlwarning ("track unknown type : %s, setting linear by default", (const char*)ptr);
-
- ptr = xmlGetProp (cur, (xmlChar*)"target");
- if (!ptr)
- {
- nlwarning ("no target for track");
- return false;
- }
-
- //
- if (!CInterfaceLink::splitLinkTargets (ptr, parentGroup, _Targets))
- {
- nlwarning ("no target for track");
- return false;
- }
-
- // Initialize the track
- switch(_Type)
- {
- case Track_Linear: _TrackKeyFramer = UTrackKeyframer::createLinearFloatTrack(); break;
- case Track_TCB: _TrackKeyFramer = UTrackKeyframer::createTCBFloatTrack(); break;
- case Track_Bezier: _TrackKeyFramer = UTrackKeyframer::createBezierFloatTrack(); break;
- default: nlstop; break;
- }
-
- cur = cur->children;
- bool ok = true;
-
- if (_Dynamic)
- {
- while (cur)
- {
- // Check that this is a key node
- if ( stricmp((char*)cur->name,"key") != 0 )
- {
- cur = cur->next;
- continue;
- }
-
- // Read time and value the 2 main key attributes
- CXMLAutoPtr time, value;
- time = xmlGetProp (cur, (xmlChar*)"time");
- value = xmlGetProp (cur, (xmlChar*)"value");
- if (!time || !value)
- {
- nlwarning("track key with no time or no value");
- ok = false;
- cur = cur->next;
- continue;
- }
-
- SDynKey k;
- k.Value = (const char*)value;
- k.Time = (const char*)time;
- if (isdigit(k.Time[0]) || (k.Time[0] == '-'))
- {
- double dTime;
- fromString(k.Time, dTime);
- k.Time = toString(dTime * CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionMulCoefAnim).getValFloat());
- }
-
- // Depending on the type of the track read extra values
- switch(_Type)
- {
- case Track_Linear:
- break;
-
- case Track_Bezier:
- {
- CXMLAutoPtr inTan, outTan, step;
- inTan = xmlGetProp (cur, (xmlChar*)"intan");
- outTan = xmlGetProp (cur, (xmlChar*)"outtan");
- step = xmlGetProp (cur, (xmlChar*)"step");
-
- if (inTan) k.InTan = (const char*)inTan;
- if (outTan) k.OutTan = (const char*)outTan;
- if (step) k.Step = (const char*)step;
- }
- break;
-
- case Track_TCB:
- {
- CXMLAutoPtr tension, continuity, bias, easeto, easefrom;
- tension = xmlGetProp (cur, (xmlChar*)"tension");
- continuity = xmlGetProp (cur, (xmlChar*)"continuity");
- bias = xmlGetProp (cur, (xmlChar*)"bias");
- easeto = xmlGetProp (cur, (xmlChar*)"easeto");
- easefrom = xmlGetProp (cur, (xmlChar*)"easefrom");
-
- if (tension) k.Tension = (const char*)tension;
- if (continuity) k.Continuity = (const char*)continuity;
- if (bias) k.Bias = (const char*)bias;
- if (easeto) k.EaseTo = (const char*)easeto;
- if (easefrom) k.EaseFrom = (const char*)easefrom;
- }
- break;
- default: nlstop; break;
- }
- _DynKeys.push_back(k);
-
- cur = cur->next;
- }
- }
- else // Static parsing
- {
- while (cur)
- {
- // Check that this is a key node
- if ( stricmp((char*)cur->name,"key") != 0 )
- {
- cur = cur->next;
- continue;
- }
-
- // Read time and value the 2 main key attributes
- CXMLAutoPtr time, value;
- time = xmlGetProp (cur, (xmlChar*)"time");
- value = xmlGetProp (cur, (xmlChar*)"value");
- if (!time || !value)
- {
- nlwarning("track key with no time or no value");
- ok = false;
- cur = cur->next;
- continue;
- }
-
- float fAnimTime;
- fromString((const char*)time, fAnimTime);
- TAnimationTime animTime = fAnimTime * CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionMulCoefAnim).getValFloat();
- double animValue;
- fromString(value, animValue);
-
- // Depending on the type of the track add the key
- switch(_Type)
- {
- case Track_Linear:
- {
- UTrackKeyframer::UKeyLinearFloat k;
- k.Time = animTime;
- k.Value = (float)animValue;
- _TrackKeyFramer->addLinearFloatKey (k);
- }
- break;
-
- case Track_Bezier:
- {
- UTrackKeyframer::UKeyBezierFloat k;
- k.Time = animTime;
- k.Value = (float)animValue;
-
- // Read extra values
- CXMLAutoPtr inTan, outTan, step;
- inTan = xmlGetProp (cur, (xmlChar*)"intan");
- outTan = xmlGetProp (cur, (xmlChar*)"outtan");
- step = xmlGetProp (cur, (xmlChar*)"step");
-
- k.TanIn = 0.0f;
- k.TanOut = 0.0f;
- k.Step = false;
-
- if (inTan) fromString((const char*)inTan, k.TanIn);
- if (outTan) fromString((const char*)outTan, k.TanOut);
- if (step) k.Step = CInterfaceElement::convertBool(step);
-
- _TrackKeyFramer->addBezierFloatKey (k);
- }
- break;
-
- case Track_TCB:
- {
- UTrackKeyframer::UKeyTCBFloat k;
- k.Time = animTime;
- k.Value = (float)animValue;
-
- // Read extra values
- CXMLAutoPtr tension, continuity, bias, easeto, easefrom;
- tension = xmlGetProp (cur, (xmlChar*)"tension");
- continuity = xmlGetProp (cur, (xmlChar*)"continuity");
- bias = xmlGetProp (cur, (xmlChar*)"bias");
- easeto = xmlGetProp (cur, (xmlChar*)"easeto");
- easefrom = xmlGetProp (cur, (xmlChar*)"easefrom");
-
- k.Tension = 0.0f;
- k.Continuity = 0.0f;
- k.Bias = 0.0f;
- k.EaseTo = 0.0f;
- k.EaseFrom = 0.0f;
-
- if (tension) fromString((const char*)tension, k.Tension);
- if (continuity) fromString((const char*)continuity, k.Continuity);
- if (bias) fromString((const char*)bias, k.Bias);
- if (easeto) fromString((const char*)easeto, k.EaseTo);
- if (easefrom) fromString((const char*)easefrom, k.EaseFrom);
-
- _TrackKeyFramer->addTCBFloatKey (k);
- }
- break;
- default: nlstop; break;
- }
- cur = cur->next;
- }
- }
- return true;
-}
-
-// ----------------------------------------------------------------------------
-void CInterfaceTrack::update (double currentTime)
-{
- float currentValue;
- UTrack *pTrack = dynamic_cast(_TrackKeyFramer);
- if (pTrack == NULL) return;
- pTrack->interpolate((TAnimationTime)currentTime, currentValue);
-
- // Update the targets
- CInterfaceExprValue expr;
- expr.setDouble(currentValue);
- for (uint i = 0; i < _Targets.size(); ++i)
- _Targets[i].affect(expr);
-}
-
-// ----------------------------------------------------------------------------
-void CInterfaceTrack::eval()
-{
- if (!_Dynamic) return;
-
- if (_TrackKeyFramer != NULL)
- delete _TrackKeyFramer;
-
- switch(_Type)
- {
- case Track_Linear:
- {
- _TrackKeyFramer = UTrackKeyframer::createLinearFloatTrack();
- for (uint i = 0; i < _DynKeys.size(); ++i)
- {
- SDynKey &rKey = _DynKeys[i];
- UTrackKeyframer::UKeyLinearFloat k;
- CInterfaceExprValue res;
- if (!rKey.Time.empty() && CInterfaceExpr::eval(rKey.Time, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert Time to double");
- else
- k.Time = (TAnimationTime)res.getDouble();
- }
- else
- {
- k.Time = 0;
- }
-
- if (!rKey.Value.empty() && CInterfaceExpr::eval(rKey.Value, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert Value to double");
- else
- k.Value = (float)res.getDouble();
- }
- else
- {
- k.Value = 0;
- }
-
- _TrackKeyFramer->addLinearFloatKey (k);
- }
- }
- break;
-
- case Track_TCB:
- {
- _TrackKeyFramer = UTrackKeyframer::createTCBFloatTrack();
- for (uint i = 0; i < _DynKeys.size(); ++i)
- {
- SDynKey &rKey = _DynKeys[i];
- UTrackKeyframer::UKeyTCBFloat k;
- CInterfaceExprValue res;
- if (!rKey.Time.empty() && CInterfaceExpr::eval(rKey.Time, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert Time to double");
- else
- k.Time = (TAnimationTime)res.getDouble();
- }
- else
- {
- k.Time = 0;
- }
-
- if (!rKey.Value.empty() && CInterfaceExpr::eval(rKey.Value, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert Value to double");
- else
- k.Value = (float)res.getDouble();
- }
- else
- {
- k.Value = 0;
- }
-
- if (!rKey.Tension.empty() && CInterfaceExpr::eval(rKey.Tension, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert Tension to double");
- else
- k.Tension = (float)res.getDouble();
- }
- else
- {
- k.Tension = 0;
- }
-
- if (!rKey.Continuity.empty() && CInterfaceExpr::eval(rKey.Continuity, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert Continuity to double");
- else
- k.Continuity = (float)res.getDouble();
- }
- else
- {
- k.Continuity = 0;
- }
-
- if (!rKey.Bias.empty() && CInterfaceExpr::eval(rKey.Bias, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert Bias to double");
- else
- k.Bias = (float)res.getDouble();
- }
- else
- {
- k.Bias = 0;
- }
-
- if (!rKey.EaseTo.empty() && CInterfaceExpr::eval(rKey.EaseTo, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert EaseTo to double");
- else
- k.EaseTo = (float)res.getDouble();
- }
- else
- {
- k.EaseTo = 0;
- }
-
- if (!rKey.EaseFrom.empty() && CInterfaceExpr::eval(rKey.EaseFrom, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert EaseFrom to double");
- else
- k.EaseFrom = (float)res.getDouble();
- }
- else
- {
- k.EaseFrom = 0;
- }
-
- _TrackKeyFramer->addTCBFloatKey (k);
- }
- }
- break;
-
- case Track_Bezier:
- {
- _TrackKeyFramer = UTrackKeyframer::createBezierFloatTrack(); break;
- for (uint i = 0; i < _DynKeys.size(); ++i)
- {
- SDynKey &rKey = _DynKeys[i];
- UTrackKeyframer::UKeyBezierFloat k;
- CInterfaceExprValue res;
- if (!rKey.Time.empty() && CInterfaceExpr::eval(rKey.Time, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert Time to double");
- else
- k.Time = (TAnimationTime)res.getDouble();
- }
- else
- {
- k.Time = 0;
- }
-
- if (!rKey.Value.empty() && CInterfaceExpr::eval(rKey.Value, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert Value to double");
- else
- k.Value = (float)res.getDouble();
- }
- else
- {
- k.Value = 0;
- }
-
- if (!rKey.InTan.empty() && CInterfaceExpr::eval(rKey.InTan, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert TanIn to double");
- else
- k.TanIn = (float)res.getDouble();
- }
- else
- {
- k.TanIn = 0;
- }
-
- if (!rKey.OutTan.empty() && CInterfaceExpr::eval(rKey.OutTan, res))
- {
- if (!res.toDouble())
- nlwarning ("cannot convert TanOut to double");
- else
- k.TanOut = (float)res.getDouble();
- }
- else
- {
- k.TanOut = 0;
- }
-
- if (!rKey.Step.empty() && CInterfaceExpr::eval(rKey.Step, res))
- {
- if (!res.toBool())
- nlwarning ("cannot convert Step to bool");
- else
- k.Step = res.getBool();
- }
- else
- {
- k.Step = false;
- }
-
- _TrackKeyFramer->addBezierFloatKey (k);
- }
- }
- default: nlstop; break;
- }
-
-}
-
-// ----------------------------------------------------------------------------
-// CInterfaceAnim
-// ----------------------------------------------------------------------------
-
-// ----------------------------------------------------------------------------
-CInterfaceAnim::CInterfaceAnim()
-{
- _CurrentTime = 0;
- _Finished = true;
- _Duration = 0;
- _DisableButtons = true;
- _AnimHasToBeStopped = false;
- _Parent = NULL;
-}
-
-// ----------------------------------------------------------------------------
-CInterfaceAnim::~CInterfaceAnim()
-{
- for (uint i = 0; i < _Tracks.size(); ++i)
- delete _Tracks[i];
-}
-
-// ----------------------------------------------------------------------------
-bool CInterfaceAnim::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
-{
- CXMLAutoPtr ptr;
-
- ptr = xmlGetProp (cur, (xmlChar*)"id");
- _Id = (const char*)ptr;
-
- ptr = xmlGetProp (cur, (xmlChar*)"duration");
- if (!ptr)
- {
- nlwarning("anim with no duration");
- return false;
- }
- fromString((const char*)ptr, _Duration);
- if (_Duration == 0)
- _Duration = 1.0;
- _Duration *= CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionMulCoefAnim).getValFloat();
-
- ptr = xmlGetProp (cur, (xmlChar*)"disable_buttons");
- if (ptr)
- _DisableButtons = CInterfaceElement::convertBool(ptr);
-
- ptr = (char*) xmlGetProp( cur, (xmlChar*)"on_finish" );
- if (ptr) _AHOnFinish = (const char *) ptr;
- ptr = (char*) xmlGetProp( cur, (xmlChar*)"on_finish_params" );
- if (ptr) _AHOnFinishParams = (const char *) ptr;
-
- cur = cur->children;
-
-// bool ok = true;
- while (cur)
- {
- // Check that this is a key node
- if ( stricmp((char*)cur->name,"track") != 0 )
- {
- cur = cur->next;
- continue;
- }
-
- CInterfaceTrack *pTrack = new CInterfaceTrack;
- if (!pTrack->parse(cur,parentGroup))
- {
- delete pTrack;
- nlwarning("track not added to anim");
- }
- else
- {
- _Tracks.push_back(pTrack);
- }
- cur = cur->next;
- }
-
- _Parent = parentGroup;
-
- return true;
-}
-
-// ----------------------------------------------------------------------------
-void CInterfaceAnim::update()
-{
- if ((_Duration == 0) || (_Finished))
- return;
-
- const CWidgetManager::SInterfaceTimes × = CWidgetManager::getInstance()->getInterfaceTimes();
-
- // Delta time limiter
- if ( ( times.frameDiffMs / 1000.0f ) > 0.1)
- _CurrentTime += 0.1;
- else
- _CurrentTime += ( times.frameDiffMs / 1000.0f );
-
- // Stop the anim if we have to
- if (_AnimHasToBeStopped)
- {
- stop();
- return;
- }
-
- // Do this here to let it play the last frame of the animation
- if (_CurrentTime >= _Duration)
- {
- _CurrentTime = _Duration;
- _AnimHasToBeStopped = true;
- }
-
- // Update tracks
- for (uint i = 0; i < _Tracks.size(); ++i)
- {
- CInterfaceTrack *pTrack = _Tracks[i];
- pTrack->update (_CurrentTime);
- }
-}
-
-// ----------------------------------------------------------------------------
-void CInterfaceAnim::start()
-{
- _CurrentTime = 0.0f;
- _Finished = false;
- _AnimHasToBeStopped = false;
-
- // Look if there are some dynamic tracks
- for (uint i = 0; i < _Tracks.size(); ++i)
- if (_Tracks[i]->isDynamic())
- _Tracks[i]->eval();
-
- // Play the first frame
- update();
-}
-
-// ----------------------------------------------------------------------------
-void CInterfaceAnim::stop()
-{
- _Finished = true;
-
- if (!_AHOnFinish.empty())
- CAHManager::getInstance()->runActionHandler(_AHOnFinish, _Parent, _AHOnFinishParams);
-}
-
-
diff --git a/code/ryzom/client/src/interface_v3/interface_anim.h b/code/ryzom/client/src/interface_v3/interface_anim.h
deleted file mode 100644
index 4154e790b..000000000
--- a/code/ryzom/client/src/interface_v3/interface_anim.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// Ryzom - MMORPG Framework
-// Copyright (C) 2010 Winch Gate Property Limited
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-
-
-#ifndef RZ_INTERFACE_ANIM_H
-#define RZ_INTERFACE_ANIM_H
-
-#include "nel/gui/interface_property.h"
-#include "nel/gui/interface_group.h"
-#include "nel/gui/interface_link.h"
-#include "nel/3d/u_track.h"
-
-/**
- * class managing an animation track
- * \author Matthieu 'TrapII' Besson
- * \author Nevrax France
- * \date 2003
- */
-class CInterfaceTrack
-{
-
-public:
-
- CInterfaceTrack();
- ~CInterfaceTrack();
-
- virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup);
-
- void update (double currentTime);
-
- bool isDynamic () { return _Dynamic; }
-
- void eval(); // Evaluate dynamic keys
-
-private:
-
- enum ETrackType
- {
- Track_Linear,
- Track_TCB,
- Track_Bezier
- };
-
- struct SDynKey
- {
- std::string Time;
- std::string Value;
- std::string InTan;
- std::string OutTan;
- std::string Step;
- std::string Tension;
- std::string Continuity;
- std::string Bias;
- std::string EaseTo;
- std::string EaseFrom;
- };
-
- bool _Dynamic;
- std::vector _DynKeys;
-
- ETrackType _Type;
- NL3D::UTrackKeyframer *_TrackKeyFramer;
- std::vector _Targets;
-};
-
-/**
- * class managing an animation of the interface
- * \author Matthieu 'TrapII' Besson
- * \author Nevrax France
- * \date 2003
- */
-class CInterfaceAnim
-{
-
-public:
-
- CInterfaceAnim();
- ~CInterfaceAnim();
-
- virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup);
-
- void update();
- void start();
- void stop();
-
- bool isFinished() { return _Finished; }
- bool isDisableButtons() { return _DisableButtons; }
-
-protected:
-
- CInterfaceGroup *_Parent;
-
- // Parsed properties
- double _Duration;
- bool _DisableButtons;
-
- std::string _AHOnFinish;
- std::string _AHOnFinishParams;
-
- std::string _Id;
-
- std::vector _Tracks;
-
- // Current anim
- double _CurrentTime;
- bool _Finished;
- bool _AnimHasToBeStopped;
-
-};
-
-#endif // NL_INTERFACE_ANIM_H
-
-/* End of interface_anim.h */
-
-
diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp
index 5a43ddbbb..dc204b2dd 100644
--- a/code/ryzom/client/src/interface_v3/interface_manager.cpp
+++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp
@@ -43,7 +43,7 @@
#include "nel/gui/action_handler.h"
#include "action_handler_misc.h"
#include "interface_observer.h"
-#include "interface_anim.h"
+#include "nel/gui/interface_anim.h"
#include "interface_ddx.h"
#include "action_handler_help.h"
#include "action_handler_item.h"
diff --git a/code/ryzom/client/src/interface_v3/interface_manager.h b/code/ryzom/client/src/interface_v3/interface_manager.h
index 9c5dd87d0..564a27525 100644
--- a/code/ryzom/client/src/interface_v3/interface_manager.h
+++ b/code/ryzom/client/src/interface_v3/interface_manager.h
@@ -71,10 +71,9 @@ namespace NLGUI
class CInterfaceOptions;
class CGroupContainer;
class CGroupMenu;
+ class CInterfaceAnim;
}
-class CInterfaceAnim;
-
/**
* class managing the interface
* \author Matthieu 'TrapII' Besson
diff --git a/code/ryzom/client/src/interface_v3/interface_parser.cpp b/code/ryzom/client/src/interface_v3/interface_parser.cpp
index a65420c01..bf120d761 100644
--- a/code/ryzom/client/src/interface_v3/interface_parser.cpp
+++ b/code/ryzom/client/src/interface_v3/interface_parser.cpp
@@ -33,7 +33,7 @@
#include "interface_observer.h"
#include "nel/gui/interface_options.h"
#include "interface_options_ryzom.h"
-#include "interface_anim.h"
+#include "nel/gui/interface_anim.h"
#include "interface_3d_scene.h"
// View
#include "nel/gui/view_bitmap.h"
diff --git a/code/ryzom/client/src/interface_v3/interface_parser.h b/code/ryzom/client/src/interface_v3/interface_parser.h
index dc240ce00..6373ae128 100644
--- a/code/ryzom/client/src/interface_v3/interface_parser.h
+++ b/code/ryzom/client/src/interface_v3/interface_parser.h
@@ -38,9 +38,9 @@ namespace NLGUI
class CCtrlBase;
class CGroupList;
class CGroupContainer;
+ class CInterfaceAnim;
}
-class CInterfaceAnim;
class CViewPointer;
class CBrickJob;