00001
00022
00023
00024
00025
00026 #ifndef __SYNFIG_STUDIO_DUCKMATIC_H
00027 #define __SYNFIG_STUDIO_DUCKMATIC_H
00028
00029
00030
00031 #include <list>
00032 #include <map>
00033 #include <set>
00034
00035 #include <ETL/smart_ptr>
00036 #include <ETL/handle>
00037
00038 #include <synfig/vector.h>
00039 #include <synfig/string.h>
00040 #include <synfig/real.h>
00041 #include <sigc++/signal.h>
00042 #include <sigc++/object.h>
00043 #include <synfig/time.h>
00044 #include <synfig/color.h>
00045 #include <ETL/smart_ptr>
00046
00047 #include "duck.h"
00048 #include <synfig/color.h>
00049 #include <synfig/guidset.h>
00050
00051
00052
00053 #ifdef HASH_MAP_H
00054 #include HASH_MAP_H
00055 #include FUNCTIONAL_H
00056
00057 #ifndef __STRING_HASH__
00058 #define __STRING_HASH__
00059 class StringHash
00060 {
00061 # ifdef FUNCTIONAL_HASH_ON_STRING
00062 HASH_MAP_NAMESPACE::hash<synfig::String> hasher_;
00063 # else // FUNCTIONAL_HASH_ON_STRING
00064 HASH_MAP_NAMESPACE::hash<const char*> hasher_;
00065 # endif // FUNCTIONAL_HASH_ON_STRING
00066 public:
00067 size_t operator()(const synfig::String& x)const
00068 {
00069 # ifdef FUNCTIONAL_HASH_ON_STRING
00070 return hasher_(x);
00071 # else // FUNCTIONAL_HASH_ON_STRING
00072 return hasher_(x.c_str());
00073 # endif // FUNCTIONAL_HASH_ON_STRING
00074 }
00075 };
00076 #endif
00077 #else
00078 #include <map>
00079 #endif
00080
00081
00082
00083
00084
00085 namespace synfigapp { class ValueDesc; }
00086 namespace synfig { class ParamDesc; }
00087
00088 namespace studio
00089 {
00090
00091 class CanvasView;
00092 class Duckmatic;
00093
00094 class DuckDrag_Base : public etl::shared_object
00095 {
00096 public:
00097 virtual void begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& begin)=0;
00098 virtual bool end_duck_drag(Duckmatic* duckmatic)=0;
00099 virtual void duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector)=0;
00100 };
00101
00102 class DuckDrag_Translate : public DuckDrag_Base
00103 {
00104 synfig::Vector last_translate_;
00105 synfig::Vector drag_offset_;
00106 synfig::Vector snap;
00107 std::vector<synfig::Vector> positions;
00108
00109 public:
00110 void begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& begin);
00111 bool end_duck_drag(Duckmatic* duckmatic);
00112 void duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector);
00113 };
00114
00123 class Duckmatic
00124 {
00125 friend class DuckDrag_Base;
00126 friend class DuckDrag_Translate;
00127
00128
00129
00130
00131
00132 public:
00133
00134 #ifdef HASH_MAP_H
00135 typedef HASH_MAP_CLASS<synfig::GUID,etl::smart_ptr<synfig::Point>,synfig::GUIDHash> DuckDataMap;
00136 #else
00137 typedef std::map<synfig::GUID,etl::smart_ptr<synfig::Point> > DuckDataMap;
00138 #endif
00139
00140 typedef studio::DuckMap DuckMap;
00141
00142 typedef studio::Duck Duck;
00143
00144 struct Stroke;
00145
00146 struct Bezier;
00147
00148 class Push;
00149
00150 friend class Push;
00151
00152 typedef Duck::Type Type;
00153
00154 typedef std::list<float> GuideList;
00155
00156
00157
00158
00159
00160 private:
00161
00162 Type type_mask;
00163
00164 DuckMap duck_map;
00165
00166 DuckDataMap duck_data_share_map;
00167
00168 std::list<etl::handle<Stroke> > stroke_list_;
00169
00170 std::list<etl::handle<Stroke> > persistent_stroke_list_;
00171
00172 synfig::GUIDSet selected_ducks;
00173
00174 synfig::GUID last_duck_guid;
00175
00176 std::list<etl::handle<Bezier> > bezier_list_;
00177
00179
00180
00181 etl::handle<DuckDrag_Base> duck_dragger_;
00182
00183 sigc::signal<void> signal_duck_selection_changed_;
00184
00185 sigc::signal<void> signal_strokes_changed_;
00186
00187 sigc::signal<void> signal_grid_changed_;
00188
00189 mutable sigc::signal<void> signal_sketch_saved_;
00190
00191 GuideList guide_list_x_;
00192 GuideList guide_list_y_;
00193
00194 mutable synfig::String sketch_filename_;
00195
00196
00197
00198
00199
00200 protected:
00201
00202 etl::handle<Bezier> selected_bezier;
00203
00204 synfig::Time cur_time;
00205
00207
00209 bool grid_snap;
00210
00211 bool guide_snap;
00212
00214
00215 synfig::Vector grid_size;
00216
00217 bool show_persistent_strokes;
00218
00219 bool axis_lock;
00220
00221
00222
00223
00224
00225 private:
00226
00227 synfig::Vector last_translate_;
00228 synfig::Vector drag_offset_;
00229
00230
00231
00232
00233
00234
00235
00236
00237 public:
00238
00239 Duckmatic();
00240 virtual ~Duckmatic();
00241
00242 sigc::signal<void>& signal_duck_selection_changed() { return signal_duck_selection_changed_; }
00243 sigc::signal<void>& signal_strokes_changed() { return signal_strokes_changed_; }
00244 sigc::signal<void>& signal_grid_changed() { return signal_grid_changed_; }
00245 sigc::signal<void>& signal_sketch_saved() { return signal_sketch_saved_; }
00246
00247 GuideList& get_guide_list_x() { return guide_list_x_; }
00248 GuideList& get_guide_list_y() { return guide_list_y_; }
00249 const GuideList& get_guide_list_x()const { return guide_list_x_; }
00250 const GuideList& get_guide_list_y()const { return guide_list_y_; }
00251
00252 void set_guide_snap(bool x=true);
00253 bool get_guide_snap()const { return guide_snap; }
00254 void toggle_guide_snap() { set_guide_snap(!get_guide_snap()); }
00255
00257 void set_grid_snap(bool x=true);
00258
00260 bool get_grid_snap()const { return grid_snap; }
00261
00262 void enable_grid_snap() { set_grid_snap(true); }
00263
00264 void disable_grid_snap() { set_grid_snap(false); }
00265
00266 void toggle_grid_snap() { set_grid_snap(!grid_snap); }
00267
00268 synfig::Point snap_point_to_grid(const synfig::Point& x, float radius=0.1)const;
00269
00270 bool get_show_persistent_strokes()const { return show_persistent_strokes; }
00271 void set_show_persistent_strokes(bool x);
00272
00274 void set_grid_size(const synfig::Vector &s);
00275
00277 const synfig::Vector &get_grid_size()const { return grid_size; }
00278
00279
00280 const synfig::Time &get_time()const { return cur_time; }
00281
00282 bool get_axis_lock()const { return axis_lock; }
00283 void set_axis_lock(bool x) { axis_lock=x; }
00284
00285 void set_time(synfig::Time x) { cur_time=x; }
00286
00287 bool is_duck_group_selectable(const etl::handle<Duck>& x)const;
00288
00289
00290 DuckList get_duck_list()const;
00291
00292 const std::list<etl::handle<Bezier> >& bezier_list()const { return bezier_list_; }
00293
00294 const std::list<etl::handle<Stroke> >& stroke_list()const { return stroke_list_; }
00295
00296 const std::list<etl::handle<Stroke> >& persistent_stroke_list()const { return persistent_stroke_list_; }
00297
00298 std::list<etl::handle<Stroke> >& persistent_stroke_list() { return persistent_stroke_list_; }
00299
00301 etl::handle<Duck> get_selected_duck()const;
00302
00303 DuckList get_selected_ducks()const;
00304
00306 bool duck_is_selected(const etl::handle<Duck> &duck)const;
00307
00308
00309 void refresh_selected_ducks();
00310
00311 void clear_selected_ducks();
00312
00313 int count_selected_ducks()const;
00314
00315 void toggle_select_duck(const etl::handle<Duck> &duck);
00316
00317 void select_duck(const etl::handle<Duck> &duck);
00318
00319 void toggle_select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br);
00320
00321 void select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br);
00322
00323 void unselect_duck(const etl::handle<Duck> &duck);
00324
00325 void start_duck_drag(const synfig::Vector& offset);
00326 void translate_selected_ducks(const synfig::Vector& vector);
00327 bool end_duck_drag();
00328
00329 void signal_edited_selected_ducks();
00330
00331 void signal_user_click_selected_ducks(int button);
00332
00333
00334 etl::handle<Duck> find_similar_duck(etl::handle<Duck> duck);
00335 etl::handle<Duck> add_similar_duck(etl::handle<Duck> duck);
00336
00337 void add_stroke(etl::smart_ptr<std::list<synfig::Point> > stroke_point_list, const synfig::Color& color=synfig::Color(0,0,0));
00338
00339 void add_persistent_stroke(etl::smart_ptr<std::list<synfig::Point> > stroke_point_list, const synfig::Color& color=synfig::Color(0,0,0));
00340
00341 void clear_persistent_strokes();
00342
00343 void add_duck(const etl::handle<Duck> &duck);
00344
00345 void add_bezier(const etl::handle<Bezier> &bezier);
00346
00347 void erase_duck(const etl::handle<Duck> &duck);
00348
00349 void erase_bezier(const etl::handle<Bezier> &bezier);
00350
00352 etl::handle<Duck> last_duck()const;
00353
00354 etl::handle<Bezier> last_bezier()const;
00355
00357
00358 etl::handle<Duck> find_duck(synfig::Point pos, synfig::Real radius=0, Duck::Type type=Duck::TYPE_DEFAULT);
00359
00360 GuideList::iterator find_guide_x(synfig::Point pos, float radius=0.1);
00361 GuideList::iterator find_guide_y(synfig::Point pos, float radius=0.1);
00362 GuideList::const_iterator find_guide_x(synfig::Point pos, float radius=0.1)const { return const_cast<Duckmatic*>(this)->find_guide_x(pos,radius); }
00363 GuideList::const_iterator find_guide_y(synfig::Point pos, float radius=0.1)const { return const_cast<Duckmatic*>(this)->find_guide_y(pos,radius); }
00364
00366
00367
00368
00370
00371 etl::handle<Bezier> find_bezier(synfig::Point pos, synfig::Real radius=0, float* location=0);
00372
00373 etl::handle<Bezier> find_bezier(synfig::Point pos, synfig::Real scale, synfig::Real radius, float* location=0);
00374
00375 bool add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<CanvasView> canvas_view, const synfig::TransformStack& transform_stack_, synfig::ParamDesc *param_desc=0, int multiple=0);
00376
00378 void set_type_mask(Type x) { type_mask=x; }
00379
00381 Type get_type_mask()const { return type_mask; }
00382
00383 void select_all_ducks();
00384 void unselect_all_ducks();
00385
00386 void clear_ducks();
00387
00388 bool save_sketch(const synfig::String& filename)const;
00389 bool load_sketch(const synfig::String& filename);
00390 const synfig::String& get_sketch_filename()const { return sketch_filename_; }
00391
00392 void set_duck_dragger(etl::handle<DuckDrag_Base> x) { duck_dragger_=x; }
00393 etl::handle<DuckDrag_Base> get_duck_dragger()const { return duck_dragger_; }
00394 void clear_duck_dragger() { duck_dragger_=new DuckDrag_Translate(); }
00395 };
00396
00397
00400 class Duckmatic::Push
00401 {
00402 Duckmatic *duckmatic_;
00403 DuckMap duck_map;
00404 std::list<etl::handle<Bezier> > bezier_list_;
00405 std::list<etl::handle<Stroke> > stroke_list_;
00406 DuckDataMap duck_data_share_map;
00407 etl::handle<DuckDrag_Base> duck_dragger_;
00408
00409 bool needs_restore;
00410
00411 public:
00412 Push(Duckmatic *duckmatic_);
00413 ~Push();
00414 void restore();
00415 };
00416
00419 struct Duckmatic::Bezier : public etl::shared_object
00420 {
00421 private:
00422 sigc::signal<void,float> signal_user_click_[5];
00423 public:
00424
00425 etl::handle<Duck> p1,p2,c1,c2;
00426 bool is_valid()const { return p1 && p2 && c1 && c2; }
00427
00428 sigc::signal<void,float> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
00429 };
00430
00433 struct Duckmatic::Stroke : public etl::shared_object
00434 {
00435 private:
00436 sigc::signal<void,float> signal_user_click_[5];
00437 public:
00438
00439 etl::smart_ptr<std::list<synfig::Point> > stroke_data;
00440
00441 synfig::Color color;
00442
00443 bool is_valid()const { return (bool)stroke_data; }
00444
00445 sigc::signal<void,float> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
00446 };
00447
00448 };
00449
00450
00451
00452 #endif