1 /***********************************************************************
2     created:    7/8/2010
3     author:     Martin Preisler
4 
5     purpose:    Defines the interface for the Affector clas
6 *************************************************************************/
7 /***************************************************************************
8  *   Copyright (C) 2004 - 2010 Paul D Turner & The CEGUI Development Team
9  *
10  *   Permission is hereby granted, free of charge, to any person obtaining
11  *   a copy of this software and associated documentation files (the
12  *   "Software"), to deal in the Software without restriction, including
13  *   without limitation the rights to use, copy, modify, merge, publish,
14  *   distribute, sublicense, and/or sell copies of the Software, and to
15  *   permit persons to whom the Software is furnished to do so, subject to
16  *   the following conditions:
17  *
18  *   The above copyright notice and this permission notice shall be
19  *   included in all copies or substantial portions of the Software.
20  *
21  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  *   OTHER DEALINGS IN THE SOFTWARE.
28  ***************************************************************************/
29 #ifndef _CEGUIAffector_h_
30 #define _CEGUIAffector_h_
31 
32 #include "CEGUI/String.h"
33 #include "CEGUI/KeyFrame.h"
34 #include <map>
35 
36 #if defined(_MSC_VER)
37 #   pragma warning(push)
38 #   pragma warning(disable : 4251)
39 #endif
40 
41 // Start of CEGUI namespace section
42 namespace CEGUI
43 {
44 
45 /*!
46 \brief
47     Defines an 'affector' class
48 
49     Affector is part of Animation definition. It is set to affect
50     one Property using one Interpolator.
51 
52 \todo
53     moveKeyFrame, this will be vital for any animation editing tools
54 */
55 class CEGUIEXPORT Affector : public AllocatedObject<Affector>
56 {
57 public:
58     //! enumerates the possible methods of application
59     enum ApplicationMethod
60     {
61         //! applies values as absolutes
62         AM_Absolute,
63 
64         /** saves a base value after the animation is started and applies
65          * relatively to that
66          */
67         AM_Relative,
68 
69         /** saves a base value after the animation is started and applies
70          * by multiplying this base value with key frame floats
71          */
72         AM_RelativeMultiply
73     };
74 
75     /** internal constructor, please construct Affectors via
76      * Animation::createAffector only
77      */
78     Affector(Animation* parent);
79 
80     //! destructor, this destroys all key frames defined inside this affector
81     ~Affector(void);
82 
83     /*!
84     \brief
85     	Retrieves the parent animation of this keyframe
86     */
getParent()87     inline Animation* getParent() const
88     {
89     	return d_parent;
90     }
91 
92     /*!
93     \brief
94         Retrieves index with which this affector is retrievable in parent Animation
95 
96     \note
97         The index is only valid as long as the list of affectors is unchanged in animation!
98     */
99     size_t getIdxInParent() const;
100 
101     /*!
102     \brief
103         Sets the application method
104 
105     \par
106         Values can be applied in 2 ways - as absolute values or relative to base
107         value that is retrieved and saved after animation is started
108     */
109     void setApplicationMethod(ApplicationMethod method);
110 
111     /*!
112     \brief
113         Retrieves current application method
114 
115     \see
116         Affector::setApplicationMethod
117     */
118     ApplicationMethod getApplicationMethod() const;
119 
120     /*!
121     \brief
122         Sets the property that will be affected
123     */
124     void setTargetProperty(const String& target);
125 
126     /*!
127     \brief
128         Gets the property that will be affected
129     */
130     const String& getTargetProperty() const;
131 
132     /*!
133     \brief
134         Sets interpolator of this Affector
135 
136     \par
137         Interpolator has to be set for the Affector to work!
138     */
139     void setInterpolator(Interpolator* interpolator);
140 
141     /*!
142     \brief
143         Sets interpolator of this Affector
144 
145     \par
146         Interpolator has to be set for the Affector to work!
147     */
148     void setInterpolator(const String& name);
149 
150     /*!
151     \brief
152         Retrieves currently used interpolator of this Affector
153     */
154     Interpolator* getInterpolator() const;
155 
156     /*!
157     \brief
158         Creates a KeyFrame at given position
159     */
160     KeyFrame* createKeyFrame(float position);
161 
162     /*!
163     \brief
164         Creates a KeyFrame at given position
165 
166     \par
167         This is a helper method, you can set all these values after you create
168         the KeyFrame
169     */
170     KeyFrame* createKeyFrame(float position, const String& value,
171                              KeyFrame::Progression progression = KeyFrame::P_Linear,
172                              const String& sourceProperty = "");
173 
174     /*!
175     \brief
176         Destroys given keyframe
177     */
178     void destroyKeyFrame(KeyFrame* keyframe);
179 
180     /*!
181     \brief
182         Retrieves a KeyFrame at given position
183     */
184     KeyFrame* getKeyFrameAtPosition(float position) const;
185 
186     /*!
187     \brief
188         Checks whether there is a key frame at given position
189     */
190     bool hasKeyFrameAtPosition(float position) const;
191 
192     /*!
193     \brief
194         Retrieves a KeyFrame with given index
195     */
196     KeyFrame* getKeyFrameAtIdx(size_t index) const;
197 
198     /*!
199     \brief
200         Returns number of key frames defined in this affector
201     */
202     size_t getNumKeyFrames() const;
203 
204     /*!
205     \brief
206         Moves given key frame to given new position
207     */
208     void moveKeyFrameToPosition(KeyFrame* keyframe, float newPosition);
209 
210     /*!
211     \brief
212         Moves key frame at given old position to given new position
213     */
214     void moveKeyFrameToPosition(float oldPosition, float newPosition);
215 
216     /*!
217      \brief
218         Internal method, causes all properties that are used by this affector
219         and it's keyframes to be saved
220 
221     \par
222         So their values are still known after
223         they've been affected.
224      */
225     void savePropertyValues(AnimationInstance* instance);
226 
227     /*!
228     \brief
229         Applies this Affector's definition with parameters from given
230         Animation Instance
231 
232     \par
233         This function is internal so unless you know what you're doing, don't
234         touch!
235 
236     \see
237         AnimationInstance
238     */
239     void apply(AnimationInstance* instance);
240 
241     /*!
242     \brief
243         Writes an xml representation of this Affector to \a out_stream.
244 
245     \param xml_stream
246         Stream where xml data should be output.
247     */
248     void writeXMLToStream(XMLSerializer& xml_stream) const;
249 
250 private:
251     //! parent animation definition
252     Animation* d_parent;
253     //! application method
254     ApplicationMethod d_applicationMethod;
255     //! property that gets affected by this affector
256     String d_targetProperty;
257     //! curently used interpolator (has to be set for the Affector to work!)
258     Interpolator* d_interpolator;
259 
260     typedef std::map<float, KeyFrame*, std::less<float>
261         CEGUI_MAP_ALLOC(float, KeyFrame*)> KeyFrameMap;
262     /** keyframes of this affector (if there are no keyframes, this affector
263      * won't do anything!)
264      */
265     KeyFrameMap d_keyFrames;
266 };
267 
268 } // End of  CEGUI namespace section
269 
270 #if defined(_MSC_VER)
271 #   pragma warning(pop)
272 #endif
273 
274 #endif  // end of guard _CEGUIAffector_h_
275 
276