mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-11-23 15:46:18 +00:00
CHANGED: #1471 CInterfaceTrack and CInterfaceAnim are now part of the NELGUI library and are under the NLGUI namespace.
--HG-- branch : gui-refactoring
This commit is contained in:
parent
cb4bc53ecd
commit
31482e873b
8 changed files with 786 additions and 777 deletions
135
code/nel/include/nel/gui/interface_anim.h
Normal file
135
code/nel/include/nel/gui/interface_anim.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
#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<SDynKey> _DynKeys;
|
||||
|
||||
ETrackType _Type;
|
||||
NL3D::UTrackKeyframer *_TrackKeyFramer;
|
||||
std::vector<CInterfaceLink::CTargetInfo> _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<CInterfaceTrack*> _Tracks;
|
||||
|
||||
// Current anim
|
||||
double _CurrentTime;
|
||||
bool _Finished;
|
||||
bool _AnimHasToBeStopped;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // NL_INTERFACE_ANIM_H
|
||||
|
||||
/* End of interface_anim.h */
|
||||
|
||||
|
647
code/nel/src/gui/interface_anim.cpp
Normal file
647
code/nel/src/gui/interface_anim.cpp
Normal file
|
@ -0,0 +1,647 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#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<UTrack*>(_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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,643 +0,0 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#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<UTrack*>(_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);
|
||||
}
|
||||
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
#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<SDynKey> _DynKeys;
|
||||
|
||||
ETrackType _Type;
|
||||
NL3D::UTrackKeyframer *_TrackKeyFramer;
|
||||
std::vector<CInterfaceLink::CTargetInfo> _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<CInterfaceTrack*> _Tracks;
|
||||
|
||||
// Current anim
|
||||
double _CurrentTime;
|
||||
bool _Finished;
|
||||
bool _AnimHasToBeStopped;
|
||||
|
||||
};
|
||||
|
||||
#endif // NL_INTERFACE_ANIM_H
|
||||
|
||||
/* End of interface_anim.h */
|
||||
|
||||
|
|
@ -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"
|
||||
|
|
|
@ -71,10 +71,9 @@ namespace NLGUI
|
|||
class CInterfaceOptions;
|
||||
class CGroupContainer;
|
||||
class CGroupMenu;
|
||||
class CInterfaceAnim;
|
||||
}
|
||||
|
||||
class CInterfaceAnim;
|
||||
|
||||
/**
|
||||
* class managing the interface
|
||||
* \author Matthieu 'TrapII' Besson
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -38,9 +38,9 @@ namespace NLGUI
|
|||
class CCtrlBase;
|
||||
class CGroupList;
|
||||
class CGroupContainer;
|
||||
class CInterfaceAnim;
|
||||
}
|
||||
|
||||
class CInterfaceAnim;
|
||||
class CViewPointer;
|
||||
class CBrickJob;
|
||||
|
||||
|
|
Loading…
Reference in a new issue