/* === S Y N F I G ========================================================= */ /*! \file action.h ** \brief Template File ** ** $Id: action.h 336 2007-03-16 00:39:42Z dooglus $ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley ** ** This package is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License as ** published by the Free Software Foundation; either version 2 of ** the License, or (at your option) any later version. ** ** This package 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 ** General Public License for more details. ** \endlegal */ /* ========================================================================= */ /* === S T A R T =========================================================== */ #ifndef __SYNFIG_APP_ACTION_H #define __SYNFIG_APP_ACTION_H /* === H E A D E R S ======================================================= */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "action_param.h" #include "editmode.h" /* === M A C R O S ========================================================= */ #define ACTION_MODULE_EXT public: \ static const char name__[], local_name__[], version__[], cvs_id__[], task__[]; \ static const Category category__; \ static const int priority__; \ static Action::Base *create(); \ virtual synfig::String get_name()const; \ virtual synfig::String get_local_name()const; #define ACTION_SET_NAME(class,x) const char class::name__[]=x #define ACTION_SET_CATEGORY(class,x) const Category class::category__(x) #define ACTION_SET_TASK(class,x) const char class::task__[]=x #define ACTION_SET_PRIORITY(class,x) const int class::priority__=x #define ACTION_SET_LOCAL_NAME(class,x) const char class::local_name__[]=x #define ACTION_SET_VERSION(class,x) const char class::version__[]=x #define ACTION_SET_CVS_ID(class,x) const char class::cvs_id__[]=x #define ACTION_INIT(class) \ Action::Base* class::create() { return new class(); } \ synfig::String class::get_name()const { return name__; } \ synfig::String class::get_local_name()const { return local_name__; } \ /* === T Y P E D E F S ===================================================== */ /* === C L A S S E S & S T R U C T S ======================================= */ namespace synfig { class ProgressCallback; class Canvas; }; // END of namespace synfig namespace synfigapp { class Instance; class Main; namespace Action { class System; //! Exception class, thrown when redoing or undoing an action class Error { public: enum Type { TYPE_UNKNOWN, TYPE_UNABLE, TYPE_BADPARAM, TYPE_CRITICAL, TYPE_NOTREADY, TYPE_BUG, TYPE_END }; private: Type type_; synfig::String desc_; public: Error(Type type, const char *format, ...): type_(type) { va_list args; va_start(args,format); desc_=etl::vstrprintf(format,args); } Error(const char *format, ...): type_(TYPE_UNKNOWN) { va_list args; va_start(args,format); desc_=etl::vstrprintf(format,args); } Error(Type type=TYPE_UNABLE): type_(type) { } Type get_type()const { return type_; } synfig::String get_desc()const { return desc_; } }; // END of class Action::Error class Param; class ParamList; class ParamDesc; class ParamVocab; // Action Category enum Category { CATEGORY_NONE =0, CATEGORY_LAYER =(1<<0), CATEGORY_CANVAS =(1<<1), CATEGORY_WAYPOINT =(1<<2), CATEGORY_ACTIVEPOINT =(1<<3), CATEGORY_VALUEDESC =(1<<4), CATEGORY_VALUENODE =(1<<5), CATEGORY_KEYFRAME =(1<<6), CATEGORY_GROUP =(1<<7), CATEGORY_OTHER =(1<<12), CATEGORY_DRAG =(1<<24), CATEGORY_HIDDEN =(1<<31), CATEGORY_ALL =(~0)-(1<<31) //!< All categories (EXCEPT HIDDEN) }; // END of enum Category inline Category operator|(Category lhs, Category rhs) { return static_cast(int(lhs)|int(rhs)); } //! Action Base Class /*! An action should implement the following functions: ** static bool is_candidate(const ParamList &x); ** - Checks the ParamList to see if this action could be performed. ** static ParamVocab get_param_vocab(); ** - Yields the ParamVocab object which describes what ** this action needs before it can perform the act. ** static Action::Base* create(); ** - Factory for creating this action from a ParamList ** */ class Base : public etl::shared_object { protected: Base() { } public: virtual ~Base() { }; //! This function will throw an Action::Error() on failure virtual void perform()=0; virtual bool set_param(const synfig::String& name, const Param &) { return false; } virtual bool is_ready()const=0; virtual synfig::String get_name()const =0; virtual synfig::String get_local_name()const { return get_name(); } void set_param_list(const ParamList &); }; // END of class Action::Base typedef Action::Base* (*Factory)(); typedef bool (*CandidateChecker)(const ParamList &x); typedef ParamVocab (*GetParamVocab)(); typedef etl::handle Handle; //! Undoable Action Base Class class Undoable : public Base { friend class System; bool active_; protected: Undoable():active_(true) { } private: void set_active(bool x) { active_=x; } public: //! This function will throw an Action::Error() on failure virtual void undo()=0; bool is_active()const { return active_; } }; // END of class Action::Undoable //! Action base class for canvas-specific actions class CanvasSpecific { private: bool is_dirty_; EditMode mode_; etl::loose_handle canvas_interface_; synfig::Canvas::Handle canvas_; protected: CanvasSpecific(const synfig::Canvas::Handle &canvas):is_dirty_(true),mode_(MODE_UNDEFINED),canvas_(canvas) { } CanvasSpecific():is_dirty_(true), mode_(MODE_UNDEFINED) { } virtual ~CanvasSpecific() { }; public: void set_canvas(synfig::Canvas::Handle x) { canvas_=x; } void set_canvas_interface(etl::loose_handle x) { canvas_interface_=x; } synfig::Canvas::Handle get_canvas()const { return canvas_; } etl::loose_handle get_canvas_interface()const { return canvas_interface_; } static ParamVocab get_param_vocab(); virtual bool set_param(const synfig::String& name, const Param &); virtual bool is_ready()const; EditMode get_edit_mode()const; void set_edit_mode(EditMode x) { mode_=x; } bool is_dirty()const { return is_dirty_; } void set_dirty(bool x=true) { is_dirty_=x; } }; // END of class Action::Undoable typedef std::list< etl::handle > ActionList; /*! \class synfigapp::Action::Super ** \brief Super-Action base class for actions composed of several other actions. ** ** Actions deriving from this class should only implement prepare(), and ** NOT implement perform() or undo(). */ class Super : public Undoable, public CanvasSpecific { ActionList action_list_; public: ActionList &action_list() { return action_list_; } const ActionList &action_list()const { return action_list_; } virtual void prepare()=0; void clear() { action_list().clear(); } bool first_time()const { return action_list_.empty(); } void add_action(etl::handle action); void add_action_front(etl::handle action); virtual void perform(); virtual void undo(); }; // END of class Action::Super class Group : public Super { synfig::String name_; ActionList action_list_; protected: bool ready_; public: Group(const synfig::String &str="Group"); virtual ~Group(); virtual synfig::String get_name()const { return name_; } virtual void prepare() { }; virtual bool set_param(const synfig::String& name, const Param &)const { return false; } virtual bool is_ready()const { return ready_; } void set_name(std::string&x) { name_=x; } }; // END of class Action::Group struct BookEntry { synfig::String name; synfig::String local_name; synfig::String version; synfig::String task; int priority; Category category; Factory factory; CandidateChecker is_candidate; GetParamVocab get_param_vocab; bool operator<(const BookEntry &rhs)const { return priority Book; class CandidateList : public std::list { public: iterator find(const synfig::String& x); const_iterator find(const synfig::String& x)const { return const_cast(this)->find(x); } }; Book& book(); Handle create(const synfig::String &name); //! Compiles a list of potential candidate actions with the given \a param_list and \a category CandidateList compile_candidate_list(const ParamList& param_list, Category category=CATEGORY_ALL); /*! \class synfigapp::Action::Main ** \brief \writeme ** ** \writeme */ class Main { friend class synfigapp::Main; Main(); public: ~Main(); }; // END of class Action::Main }; // END of namespace Action }; // END of namespace synfigapp /* === E N D =============================================================== */ #endif