1 /* === S Y N F I G ========================================================= */
3 ** \brief Template File
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2008 Chris Moore
11 ** This package is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU General Public License as
13 ** published by the Free Software Foundation; either version 2 of
14 ** the License, or (at your option) any later version.
16 ** This package is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** General Public License for more details.
22 /* ========================================================================= */
24 /* === S T A R T =========================================================== */
26 #ifndef __SYNFIG_APP_ACTION_H
27 #define __SYNFIG_APP_ACTION_H
29 /* === H E A D E R S ======================================================= */
31 #include <synfig/string.h>
32 #include <synfig/canvas.h>
34 #include <ETL/stringf>
35 #include <ETL/trivial>
40 #include <synfig/layer.h>
41 #include <synfig/canvas.h>
42 #include <synfig/valuenode.h>
43 #include <synfigapp/value_desc.h>
44 #include <synfig/value.h>
45 #include <synfig/activepoint.h>
46 #include <synfig/valuenode_animated.h>
47 #include <synfig/string.h>
48 #include <synfig/keyframe.h>
50 #include "action_param.h"
53 /* === M A C R O S ========================================================= */
55 #define ACTION_MODULE_EXT public: \
56 static const char name__[], local_name__[], version__[], cvs_id__[], task__[]; \
57 static const Category category__; \
58 static const int priority__; \
59 static Action::Base *create(); \
60 virtual synfig::String get_name()const; \
61 virtual synfig::String get_local_name()const;
64 #define ACTION_SET_NAME(class,x) const char class::name__[]=x
66 #define ACTION_SET_CATEGORY(class,x) const Category class::category__(x)
68 #define ACTION_SET_TASK(class,x) const char class::task__[]=x
70 #define ACTION_SET_PRIORITY(class,x) const int class::priority__=x
72 #define ACTION_SET_LOCAL_NAME(class,x) const char class::local_name__[]=x
74 #define ACTION_SET_VERSION(class,x) const char class::version__[]=x
76 #define ACTION_SET_CVS_ID(class,x) const char class::cvs_id__[]=x
78 //! don't define get_local_name() - allow the action code to define its own
79 #define ACTION_INIT_NO_GET_LOCAL_NAME(class) \
80 Action::Base* class::create() { return new class(); } \
81 synfig::String class::get_name()const { return name__; }
83 #define ACTION_INIT(class) \
84 ACTION_INIT_NO_GET_LOCAL_NAME(class) \
85 synfig::String class::get_local_name()const { return dgettext("synfigstudio",local_name__); }
87 /* === T Y P E D E F S ===================================================== */
89 /* === C L A S S E S & S T R U C T S ======================================= */
92 class ProgressCallback;
94 }; // END of namespace synfig
106 //! Exception class, thrown when redoing or undoing an action
124 synfig::String desc_;
128 Error(Type type, const char *format, ...):
132 va_start(args,format);
133 desc_=etl::vstrprintf(format,args);
136 Error(const char *format, ...):
140 va_start(args,format);
141 desc_=etl::vstrprintf(format,args);
144 Error(Type type=TYPE_UNABLE):
149 Type get_type()const { return type_; }
150 synfig::String get_desc()const { return desc_; }
152 }; // END of class Action::Error
163 CATEGORY_LAYER =(1<<0),
164 CATEGORY_CANVAS =(1<<1),
165 CATEGORY_WAYPOINT =(1<<2),
166 CATEGORY_ACTIVEPOINT =(1<<3),
167 CATEGORY_VALUEDESC =(1<<4),
168 CATEGORY_VALUENODE =(1<<5),
169 CATEGORY_KEYFRAME =(1<<6),
170 CATEGORY_GROUP =(1<<7),
171 CATEGORY_BEZIER =(1<<8),
173 CATEGORY_OTHER =(1<<12),
175 CATEGORY_DRAG =(1<<24),
177 CATEGORY_HIDDEN =(1<<31),
178 CATEGORY_ALL =(~0)-(1<<31) //!< All categories (EXCEPT HIDDEN)
179 }; // END of enum Category
181 inline Category operator|(Category lhs, Category rhs)
182 { return static_cast<Category>(int(lhs)|int(rhs)); }
186 //! Top-level base class for all actions
187 /*! An action should implement the following functions:
188 ** - static bool is_candidate(const ParamList &x);
189 ** - Checks the ParamList to see if this action could be performed.
190 ** - static ParamVocab get_param_vocab();
191 ** - Yields the ParamVocab object which describes what
192 ** this action needs before it can perform the act.
193 ** - static Action::Base* create();
194 ** - Factory for creating this action from a ParamList
197 class Base : public etl::shared_object
205 //! This function will throw an Action::Error() on failure
206 virtual void perform()=0;
208 virtual bool set_param(const synfig::String& /*name*/, const Param &) { return false; }
209 virtual bool is_ready()const=0;
211 virtual synfig::String get_name()const =0;
212 virtual synfig::String get_local_name()const { return get_name(); }
214 void set_param_list(const ParamList &);
216 static synfig::String get_layer_descriptions(const std::list<synfig::Layer::Handle> layers, synfig::String singular_prefix = "", synfig::String plural_prefix = "");
217 static synfig::String get_layer_descriptions(const std::list<std::pair<synfig::Layer::Handle,int> > layers, synfig::String singular_prefix = "", synfig::String plural_prefix = "");
218 }; // END of class Action::Base
220 typedef Action::Base* (*Factory)();
221 typedef bool (*CandidateChecker)(const ParamList &x);
222 typedef ParamVocab (*GetParamVocab)();
224 typedef etl::handle<Base> Handle;
226 //! Undoable Action Base Class
227 class Undoable : public Base
233 Undoable():active_(true) { }
236 void set_active(bool x) { active_=x; }
240 //! This function will throw an Action::Error() on failure
241 virtual void undo()=0;
243 bool is_active()const { return active_; }
245 }; // END of class Action::Undoable
247 //! Action base class for canvas-specific actions
254 etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
255 synfig::Canvas::Handle canvas_;
258 CanvasSpecific(const synfig::Canvas::Handle &canvas):is_dirty_(true),mode_(MODE_UNDEFINED),canvas_(canvas) { }
259 CanvasSpecific():is_dirty_(true), mode_(MODE_UNDEFINED) { }
261 virtual ~CanvasSpecific() { };
266 void set_canvas(synfig::Canvas::Handle x) { canvas_=x; }
267 void set_canvas_interface(etl::loose_handle<synfigapp::CanvasInterface> x) { canvas_interface_=x; }
269 synfig::Canvas::Handle get_canvas()const { return canvas_; }
270 etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
272 static ParamVocab get_param_vocab();
273 virtual bool set_param(const synfig::String& name, const Param &);
274 virtual bool is_ready()const;
276 EditMode get_edit_mode()const;
278 void set_edit_mode(EditMode x) { mode_=x; }
280 bool is_dirty()const { return is_dirty_; }
281 void set_dirty(bool x=true) { is_dirty_=x; }
283 }; // END of class Action::Undoable
285 typedef std::list< etl::handle<Action::Undoable> > ActionList;
287 /*! \class synfigapp::Action::Super
288 ** \brief Super-Action base class for actions composed of several other actions.
290 ** Actions deriving from this class should only implement prepare(), and
291 ** NOT implement perform() or undo().
293 class Super : public Undoable, public CanvasSpecific
295 ActionList action_list_;
299 ActionList &action_list() { return action_list_; }
300 const ActionList &action_list()const { return action_list_; }
302 virtual void prepare()=0;
304 void clear() { action_list().clear(); }
306 bool first_time()const { return action_list_.empty(); }
308 void add_action(etl::handle<Undoable> action);
310 void add_action_front(etl::handle<Undoable> action);
312 virtual void perform();
315 }; // END of class Action::Super
318 class Group : public Super
320 synfig::String name_;
322 ActionList action_list_;
326 Group(const synfig::String &str="Group");
329 virtual synfig::String get_name()const { return name_; }
331 virtual void prepare() { };
333 virtual bool set_param(const synfig::String& /*name*/, const Param &)const { return false; }
334 virtual bool is_ready()const { return ready_; }
336 void set_name(std::string&x) { name_=x; }
337 }; // END of class Action::Group
346 synfig::String local_name;
347 synfig::String version;
352 CandidateChecker is_candidate;
353 GetParamVocab get_param_vocab;
355 bool operator<(const BookEntry &rhs)const { return priority<rhs.priority; }
356 }; // END of struct BookEntry
358 typedef std::map<synfig::String,BookEntry> Book;
360 class CandidateList : public std::list<BookEntry>
363 iterator find(const synfig::String& x);
364 const_iterator find(const synfig::String& x)const { return const_cast<CandidateList*>(this)->find(x); }
369 Handle create(const synfig::String &name);
371 //! Compiles a list of potential candidate actions with the given \a param_list and \a category
372 CandidateList compile_candidate_list(const ParamList& param_list, Category category=CATEGORY_ALL);
374 /*! \class synfigapp::Action::Main
381 friend class synfigapp::Main;
388 }; // END of class Action::Main
390 }; // END of namespace Action
392 }; // END of namespace synfigapp
394 /* === E N D =============================================================== */