my log
[synfig.git] / synfig-studio / trunk / src / synfigapp / action.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file action.h
3 **      \brief Template File
4 **
5 **      $Id: action.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === S T A R T =========================================================== */
23
24 #ifndef __SYNFIG_APP_ACTION_H
25 #define __SYNFIG_APP_ACTION_H
26
27 /* === H E A D E R S ======================================================= */
28
29 #include <synfig/string.h>
30 #include <synfig/canvas.h>
31 #include <ETL/handle>
32 #include <ETL/stringf>
33 #include <ETL/trivial>
34
35 #include <map>
36 #include <list>
37
38 #include <synfig/layer.h>
39 #include <synfig/canvas.h>
40 #include <synfig/valuenode.h>
41 #include <synfigapp/value_desc.h>
42 #include <synfig/value.h>
43 #include <synfig/activepoint.h>
44 #include <synfig/valuenode_animated.h>
45 #include <synfig/string.h>
46 #include <synfig/keyframe.h>
47
48 #include "action_param.h"
49 #include "editmode.h"
50
51 /* === M A C R O S ========================================================= */
52
53 #define ACTION_MODULE_EXT public: \
54         static const char name__[], local_name__[], version__[], cvs_id__[], task__[]; \
55         static const Category category__; \
56         static const int priority__; \
57         static Action::Base *create(); \
58         virtual synfig::String get_name()const; \
59         virtual synfig::String get_local_name()const;
60
61
62 #define ACTION_SET_NAME(class,x) const char class::name__[]=x
63
64 #define ACTION_SET_CATEGORY(class,x) const Category class::category__(x)
65
66 #define ACTION_SET_TASK(class,x) const char class::task__[]=x
67
68 #define ACTION_SET_PRIORITY(class,x) const int class::priority__=x
69
70 #define ACTION_SET_LOCAL_NAME(class,x) const char class::local_name__[]=x
71
72 #define ACTION_SET_VERSION(class,x) const char class::version__[]=x
73
74 #define ACTION_SET_CVS_ID(class,x) const char class::cvs_id__[]=x
75
76 #define ACTION_INIT(class) \
77         Action::Base* class::create() { return new class(); }   \
78         synfig::String class::get_name()const { return name__; }        \
79         synfig::String class::get_local_name()const { return local_name__; }    \
80
81 /* === T Y P E D E F S ===================================================== */
82
83 /* === C L A S S E S & S T R U C T S ======================================= */
84
85 namespace synfig {
86 class ProgressCallback;
87 class Canvas;
88 }; // END of namespace synfig
89
90 namespace synfigapp {
91
92 class Instance;
93 class Main;
94         
95 namespace Action {      
96
97 class System;
98         
99
100 //! Exception class, thrown when redoing or undoing an action
101 class Error
102 {
103 public:
104         enum Type
105         {
106                 TYPE_UNKNOWN,
107                 TYPE_UNABLE,
108                 TYPE_BADPARAM,
109                 TYPE_CRITICAL,
110                 TYPE_NOTREADY,
111                 TYPE_BUG,
112
113                 TYPE_END
114         };
115 private:
116
117         Type type_;
118         synfig::String desc_;
119
120 public:
121         
122         Error(Type type, const char *format, ...):
123                 type_(type)
124         {
125                 va_list args;
126                 va_start(args,format);
127                 desc_=etl::vstrprintf(format,args);
128         }
129
130         Error(const char *format, ...):
131                 type_(TYPE_UNKNOWN)
132         {
133                 va_list args;
134                 va_start(args,format);
135                 desc_=etl::vstrprintf(format,args);
136         }
137
138         Error(Type type=TYPE_UNABLE):
139                 type_(type)
140         {
141         }
142         
143         Type get_type()const { return type_; }
144         synfig::String get_desc()const { return desc_; }
145         
146 }; // END of class Action::Error
147
148 class Param;
149 class ParamList;
150 class ParamDesc;
151 class ParamVocab;
152
153 // Action Category
154 enum Category
155 {
156         CATEGORY_NONE                   =0,
157         CATEGORY_LAYER                  =(1<<0),
158         CATEGORY_CANVAS                 =(1<<1),
159         CATEGORY_WAYPOINT               =(1<<2),
160         CATEGORY_ACTIVEPOINT    =(1<<3),
161         CATEGORY_VALUEDESC              =(1<<4),
162         CATEGORY_VALUENODE              =(1<<5),
163         CATEGORY_KEYFRAME               =(1<<6),
164         CATEGORY_GROUP                  =(1<<7),
165
166         CATEGORY_OTHER                  =(1<<12),
167
168         CATEGORY_DRAG                   =(1<<24),
169         
170         CATEGORY_HIDDEN                 =(1<<31),
171         CATEGORY_ALL                    =(~0)-(1<<31)           //!< All categories (EXCEPT HIDDEN)
172 }; // END of enum Category
173
174 inline Category operator|(Category lhs, Category rhs)
175 { return static_cast<Category>(int(lhs)|int(rhs)); }
176
177
178
179 //! Action Base Class
180 /*!     An action should implement the following functions:
181 **      static bool is_canidate(const ParamList &x);
182 **              -       Checks the ParamList to see if this action could be performed.
183 **      static ParamVocab get_param_vocab();
184 **              -       Yields the ParamVocab object which describes what
185 **                      this action needs before it can perform the act.
186 **      static Action::Base* create();
187 **              -       Factory for creating this action from a ParamList
188 **
189 */
190 class Base : public etl::shared_object 
191 {
192 protected:
193         Base() { }
194         
195 public:
196         virtual ~Base() { };
197
198         //! This function will throw an Action::Error() on failure
199         virtual void perform()=0;
200         
201         virtual bool set_param(const synfig::String& name, const Param &) { return false; }
202         virtual bool is_ready()const=0;
203         
204         virtual synfig::String get_name()const =0;
205         virtual synfig::String get_local_name()const { return get_name(); }
206
207         void set_param_list(const ParamList &);
208         
209 }; // END of class Action::Base
210
211 typedef Action::Base* (*Factory)();
212 typedef bool (*CanidateChecker)(const ParamList &x);
213 typedef ParamVocab (*GetParamVocab)();
214
215 typedef etl::handle<Base> Handle;
216
217 //! Undoable Action Base Class
218 class Undoable : public Base
219 {
220         friend class System;
221         bool active_;
222
223 protected:
224         Undoable():active_(true) { }
225
226 private:
227         void set_active(bool x) { active_=x; }
228
229 public:
230
231         //! This function will throw an Action::Error() on failure
232         virtual void undo()=0;
233
234         bool is_active()const { return active_; }
235
236 }; // END of class Action::Undoable
237
238 //! Action base class for canvas-specific actions
239 class CanvasSpecific 
240 {
241 private:
242         bool is_dirty_;
243         EditMode        mode_;
244
245         etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
246         synfig::Canvas::Handle canvas_;
247
248 protected:
249         CanvasSpecific(const synfig::Canvas::Handle &canvas):is_dirty_(true),mode_(MODE_UNDEFINED),canvas_(canvas) { }
250         CanvasSpecific():mode_(MODE_UNDEFINED) { }
251
252         virtual ~CanvasSpecific() { };
253         
254         
255 public:
256
257         void set_canvas(synfig::Canvas::Handle x) { canvas_=x; }
258         void set_canvas_interface(etl::loose_handle<synfigapp::CanvasInterface> x) { canvas_interface_=x; }
259
260         synfig::Canvas::Handle get_canvas()const { return canvas_; }
261         etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
262
263         static ParamVocab get_param_vocab();
264         virtual bool set_param(const synfig::String& name, const Param &);
265         virtual bool is_ready()const;
266
267         EditMode get_edit_mode()const;
268
269         void set_edit_mode(EditMode x) { mode_=x; }
270         
271         bool is_dirty()const { return is_dirty_; }
272         void set_dirty(bool x=true) { is_dirty_=x; }
273         
274 }; // END of class Action::Undoable
275
276 typedef std::list< etl::handle<Action::Undoable> > ActionList;
277
278 /*!     \class synfigapp::Action::Super
279 **      \brief Super-Action base class for actions composed of several other actions.
280 **
281 **      Actions deriving from this class should only implement prepare(), and
282 **      NOT implement perform() or undo().
283 */
284 class Super : public Undoable, public CanvasSpecific
285 {
286         ActionList action_list_;
287
288 public:
289
290         ActionList &action_list() { return action_list_; }
291         const ActionList &action_list()const { return action_list_; }
292
293         virtual void prepare()=0;
294
295         void clear() { action_list().clear(); }
296         
297         bool first_time()const { return action_list_.empty(); }
298         
299         void add_action(etl::handle<Undoable> action);
300
301         void add_action_front(etl::handle<Undoable> action);
302
303         virtual void perform();
304         virtual void undo();
305
306 }; // END of class Action::Super
307
308
309 class Group : public Super
310 {
311         synfig::String name_;
312
313         ActionList action_list_;
314 protected:
315         bool ready_;
316 public:
317         Group(const synfig::String &str="Group");
318         virtual ~Group();
319
320         virtual synfig::String get_name()const { return name_; }
321
322         virtual void prepare() { };
323
324         virtual bool set_param(const synfig::String& name, const Param &)const { return false; }
325         virtual bool is_ready()const { return ready_; }
326
327         void set_name(std::string&x) { name_=x; }
328 }; // END of class Action::Group
329
330
331
332
333
334 struct BookEntry
335 {
336         synfig::String  name;
337         synfig::String  local_name;
338         synfig::String  version;
339         synfig::String  task;
340         int                     priority;
341         Category                category;
342         Factory                 factory;
343         CanidateChecker is_canidate;
344         GetParamVocab   get_param_vocab;        
345         
346         bool operator<(const BookEntry &rhs)const { return priority<rhs.priority; }
347 }; // END of struct BookEntry
348
349 typedef std::map<synfig::String,BookEntry> Book;
350
351 class CanidateList : public std::list<BookEntry>
352 {
353 public:
354         iterator find(const synfig::String& x);
355         const_iterator find(const synfig::String& x)const { return const_cast<CanidateList*>(this)->find(x); }
356 };
357
358 Book& book();
359
360 Handle create(const synfig::String &name);
361
362 //! Compiles a list of potential canidate actions with the given \a param_list and \a category
363 CanidateList compile_canidate_list(const ParamList& param_list, Category category=CATEGORY_ALL);
364
365 /*!     \class synfigapp::Action::Main
366 **      \brief \writeme
367 **
368 **      \writeme
369 */
370 class Main
371 {
372         friend class synfigapp::Main;
373
374         Main();
375
376 public:
377         ~Main();
378
379 }; // END of class Action::Main
380
381 }; // END of namespace Action
382
383 }; // END of namespace synfigapp
384
385 /* === E N D =============================================================== */
386
387 #endif