source: synfigstudio/trunk/fuentes/src/gui/states/state_circle.cpp @ 481

Last change on this file since 481 was 481, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 50.6 KB
Line 
1/* === S Y N F I G ========================================================= */
2/*!     \file state_circle.cpp
3**      \brief Template File
4**
5**      $Id$
6**
7**      \legal
8**      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9**      Copyright (c) 2008 Chris Moore
10**
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.
15**
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.
20**      \endlegal
21*/
22/* ========================================================================= */
23
24/* === H E A D E R S ======================================================= */
25
26#ifdef USING_PCH
27#       include "pch.h"
28#else
29#ifdef HAVE_CONFIG_H
30#       include <config.h>
31#endif
32
33#include <synfig/valuenodes/valuenode_dynamiclist.h>
34#include <synfigapp/action_system.h>
35#include <synfig/valuenodes/valuenode_bline.h>
36
37#include "state_circle.h"
38#include "state_normal.h"
39#include "canvasview.h"
40#include "workarea.h"
41#include "app.h"
42
43#include <synfigapp/action.h>
44#include "event_mouse.h"
45#include "event_layerclick.h"
46#include "docks/dock_toolbox.h"
47#include "docks/dialog_tooloptions.h"
48#include "duck.h"
49#include "widgets/widget_enum.h"
50#include "widgets/widget_distance.h"
51#include <synfigapp/main.h>
52
53#include "general.h"
54
55#endif
56
57/* === U S I N G =========================================================== */
58
59using namespace std;
60using namespace etl;
61using namespace synfig;
62using namespace studio;
63
64/* === M A C R O S ========================================================= */
65enum CircleFalloff
66{
67        CIRCLE_SQUARED  =0,
68        CIRCLE_INTERPOLATION_LINEAR     =1,
69        CIRCLE_COSINE   =2,
70        CIRCLE_SIGMOND  =3,
71        CIRCLE_SQRT             =4,
72        CIRCLE_NUM_FALLOFF
73};
74
75#ifndef LAYER_CREATION
76#define LAYER_CREATION(button, stockid, tooltip)        \
77        { \
78                Gtk::Image *icon = manage(new Gtk::Image(Gtk::StockID(stockid), \
79                        Gtk::ICON_SIZE_SMALL_TOOLBAR)); \
80                button.add(*icon); \
81        } \
82        button.set_relief(Gtk::RELIEF_NONE); \
83        button.set_tooltip_text(tooltip) ;\
84        button.signal_toggled().connect(sigc::mem_fun(*this, \
85                &studio::StateCircle_Context::toggle_layer_creation))
86#endif
87
88// indentation for options layout
89#ifndef SPACING
90#define SPACING(name, px) \
91        Gtk::Alignment *name = Gtk::manage(new Gtk::Alignment()); \
92        name->set_size_request(px)
93#endif
94
95#define GAP     (3)
96#define INDENTATION (6)
97
98/* === G L O B A L S ======================================================= */
99
100StateCircle studio::state_circle;
101
102/* === C L A S S E S & S T R U C T S ======================================= */
103
104class studio::StateCircle_Context : public sigc::trackable
105{
106        etl::handle<CanvasView> canvas_view_;
107        CanvasView::IsWorking is_working;
108
109        Duckmatic::Push duckmatic_push;
110
111        Point point_holder;
112
113        etl::handle<Duck> point2_duck;
114
115        void refresh_ducks();
116
117        bool prev_workarea_layer_status_;
118
119        //Toolbox settings
120        synfigapp::Settings& settings;
121
122        // holder of options
123        Gtk::Table options_table;
124
125        // title
126        Gtk::Label title_label;
127
128        // layer name:
129        Gtk::Label id_label;
130        Gtk::HBox id_box;
131        Gtk::Entry id_entry;
132
133        // layer types to create:
134        Gtk::Label layer_types_label;
135        Gtk::ToggleButton layer_circle_togglebutton;
136        Gtk::ToggleButton layer_region_togglebutton;
137        Gtk::ToggleButton layer_outline_togglebutton;
138        Gtk::ToggleButton layer_advanced_outline_togglebutton;
139        Gtk::ToggleButton layer_curve_gradient_togglebutton;
140        Gtk::ToggleButton layer_plant_togglebutton;
141        Gtk::HBox layer_types_box;
142
143        // blend method
144        Gtk::Label blend_label;
145        Gtk::HBox blend_box;
146        Widget_Enum blend_enum;
147
148        // opacity
149        Gtk::Label opacity_label;
150        Gtk::HScale opacity_hscl;
151
152        // brush size
153        Gtk::Label bline_width_label;
154        Widget_Distance bline_width_dist;
155
156        // spline points
157        Gtk::Label bline_points_label;
158        Glib::RefPtr<Gtk::Adjustment> number_of_bline_points_adj;
159        Gtk::SpinButton number_of_bline_points_spin;
160
161        // spline point angle offset
162        Gtk::Label bline_point_angle_offset_label;
163        Glib::RefPtr<Gtk::Adjustment> bline_point_angle_offset_adj;
164        Gtk::SpinButton bline_point_angle_offset_spin;
165        Gtk::HBox bline_point_angle_offset_box;
166
167        // invert
168        Gtk::Label invert_label;
169        Gtk::CheckButton invert_checkbutton;
170        Gtk::HBox invert_box;
171
172        // feather size
173        Gtk::Label feather_label;
174        Widget_Distance feather_dist;
175
176        // falloff of feather of circle layer
177        Gtk::Label falloff_label;
178        Gtk::HBox falloff_box;
179        Widget_Enum falloff_enum;
180
181        // link origins
182        Gtk::Label link_origins_label;
183        Gtk::CheckButton layer_link_origins_checkbutton;
184        Gtk::HBox link_origins_box;
185
186        // spline origins at center
187        Gtk::Label origins_at_center_label;
188        Gtk::CheckButton layer_origins_at_center_checkbutton;
189        Gtk::HBox origins_at_center_box;
190
191public:
192
193        // this only counts the layers which will have their origins linked
194        int layers_to_create()const
195        {
196                return
197                        (get_layer_circle_flag() && get_layer_origins_at_center_flag()) +
198                        get_layer_region_flag() +
199                        get_layer_outline_flag() +
200                        get_layer_advanced_outline_flag() +
201                        get_layer_curve_gradient_flag() +
202                        get_layer_plant_flag();
203        }
204
205        synfig::String get_id()const { return id_entry.get_text(); }
206        void set_id(const synfig::String& x) { return id_entry.set_text(x); }
207
208        int get_falloff()const { return falloff_enum.get_value(); }
209        void set_falloff(int x) { return falloff_enum.set_value(x); }
210
211        int get_blend()const { return blend_enum.get_value(); }
212        void set_blend(int x) { return blend_enum.set_value(x); }
213
214        Real get_opacity()const { return opacity_hscl.get_value(); }
215        void set_opacity(Real x) { opacity_hscl.set_value(x); }
216
217        Real get_bline_width() const {
218                return bline_width_dist.get_value().get(
219                        Distance::SYSTEM_UNITS,
220                        get_canvas_view()->get_canvas()->rend_desc()
221                );
222        }
223        void set_bline_width(Distance x) { return bline_width_dist.set_value(x);}
224
225        Real get_feather_size() const {
226                return feather_dist.get_value().get(
227                        Distance::SYSTEM_UNITS,
228                        get_canvas_view()->get_canvas()->rend_desc()
229                );
230        }
231        void set_feather_size(Distance x) { return feather_dist.set_value(x);}
232
233        Real get_number_of_bline_points()const { return number_of_bline_points_adj->get_value(); }
234        void set_number_of_bline_points(Real f) { number_of_bline_points_adj->set_value(f); }
235
236        Real get_bline_point_angle_offset()const { return bline_point_angle_offset_adj->get_value(); }
237        void set_bline_point_angle_offset(Real f) { bline_point_angle_offset_adj->set_value(f); }
238
239        bool get_invert()const { return invert_checkbutton.get_active(); }
240        void set_invert(bool i) { invert_checkbutton.set_active(i); }
241
242  bool pre_layer_circle_flag();
243        bool get_layer_circle_flag()const { return layer_circle_togglebutton.get_active(); }
244        void set_layer_circle_flag(bool x) { return layer_circle_togglebutton.set_active(x); }
245
246        bool get_layer_region_flag()const { return layer_region_togglebutton.get_active(); }
247        void set_layer_region_flag(bool x) { return layer_region_togglebutton.set_active(x); }
248
249        bool get_layer_outline_flag()const { return layer_outline_togglebutton.get_active(); }
250        void set_layer_outline_flag(bool x) { return layer_outline_togglebutton.set_active(x); }
251
252        bool get_layer_advanced_outline_flag()const { return layer_advanced_outline_togglebutton.get_active(); }
253        void set_layer_advanced_outline_flag(bool x) { return layer_advanced_outline_togglebutton.set_active(x); }
254
255        bool get_layer_curve_gradient_flag()const { return layer_curve_gradient_togglebutton.get_active(); }
256        void set_layer_curve_gradient_flag(bool x) { return layer_curve_gradient_togglebutton.set_active(x); }
257
258        bool get_layer_plant_flag()const { return layer_plant_togglebutton.get_active(); }
259        void set_layer_plant_flag(bool x) { return layer_plant_togglebutton.set_active(x); }
260
261        bool get_layer_link_origins_flag()const { return layer_link_origins_checkbutton.get_active(); }
262        void set_layer_link_origins_flag(bool x) { return layer_link_origins_checkbutton.set_active(x); }
263
264        bool get_layer_origins_at_center_flag()const { return layer_origins_at_center_checkbutton.get_active(); }
265        void set_layer_origins_at_center_flag(bool x) { return layer_origins_at_center_checkbutton.set_active(x); }
266
267  bool layer_circle_flag;
268  bool layer_region_flag;
269  bool layer_outline_flag;
270  bool layer_advanced_outline_flag;
271  bool layer_curve_gradient_flag;
272  bool layer_plant_flag;
273
274        void refresh_tool_options(); //to refresh the toolbox
275
276        //events
277        Smach::event_result event_stop_handler(const Smach::event& x);
278        Smach::event_result event_refresh_handler(const Smach::event& x);
279        Smach::event_result event_mouse_click_handler(const Smach::event& x);
280        Smach::event_result event_refresh_tool_options(const Smach::event& x);
281
282        //constructor destructor
283        StateCircle_Context(CanvasView* canvas_view);
284        ~StateCircle_Context();
285
286        //Canvas interaction
287        const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
288        etl::handle<synfigapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
289        synfig::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
290        WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
291
292        //Modifying settings etc.
293        void load_settings();
294        void save_settings();
295        void reset();
296        void increment_id();
297        bool egress_on_selection_change;
298        Smach::event_result event_layer_selection_changed_handler(const Smach::event& /*x*/)
299        {
300                if(egress_on_selection_change)
301                        throw &state_normal;
302                return Smach::RESULT_OK;
303        }
304
305        void make_circle(const Point& p1, const Point& p2);
306
307        void toggle_layer_creation();
308
309};      // END of class StateCircle_Context
310
311/* === M E T H O D S ======================================================= */
312
313StateCircle::StateCircle():
314        Smach::state<StateCircle_Context>("circle")
315{
316        insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StateCircle_Context::event_layer_selection_changed_handler));
317        insert(event_def(EVENT_STOP,&StateCircle_Context::event_stop_handler));
318        insert(event_def(EVENT_REFRESH,&StateCircle_Context::event_refresh_handler));
319        insert(event_def(EVENT_REFRESH_DUCKS,&StateCircle_Context::event_refresh_handler));
320        insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateCircle_Context::event_mouse_click_handler));
321        insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateCircle_Context::event_mouse_click_handler));
322        insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateCircle_Context::event_mouse_click_handler));
323        insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateCircle_Context::event_refresh_tool_options));
324}
325
326StateCircle::~StateCircle()
327{
328}
329
330void
331StateCircle_Context::load_settings()
332{
333        try
334        {
335                synfig::ChangeLocale change_locale(LC_NUMERIC, "C");
336                String value;
337
338                //parse the arguments yargh!
339                if(settings.get_value("circle.id",value))
340                        set_id(value);
341                else
342                        set_id("Circle");
343
344                if(settings.get_value("circle.fallofftype",value) && value != "")
345                        set_falloff(atoi(value.c_str()));
346                else
347                        set_falloff(2);
348
349                if(settings.get_value("circle.blend",value) && value != "")
350                        set_blend(atoi(value.c_str()));
351                else
352                        set_blend(0);//(int)Color::BLEND_COMPOSITE); //0 should be blend composites value
353
354                if(settings.get_value("circle.opacity",value))
355                        set_opacity(atof(value.c_str()));
356                else
357                        set_opacity(1);
358
359                if(settings.get_value("circle.bline_width",value) && value != "")
360                        set_bline_width(Distance(atof(value.c_str()), App::distance_system));
361                else
362                        set_bline_width(Distance(1, App::distance_system)); // default width
363
364                if(settings.get_value("circle.feather",value))
365                        set_feather_size(Distance(atof(value.c_str()), App::distance_system));
366                else
367                        set_feather_size(Distance(0, App::distance_system)); // default feather
368
369                if(settings.get_value("circle.number_of_bline_points",value))
370                        set_number_of_bline_points(atof(value.c_str()));
371                else
372                        set_number_of_bline_points(4);
373
374                if(settings.get_value("circle.bline_point_angle_offset",value))
375                        set_bline_point_angle_offset(atof(value.c_str()));
376                else
377                        set_bline_point_angle_offset(0);
378
379                if(settings.get_value("circle.invert",value) && value != "0")
380                        set_invert(true);
381                else
382                        set_invert(false);
383
384                if(settings.get_value("circle.layer_circle",value) && value=="0")
385                        set_layer_circle_flag(false);
386                else
387                        set_layer_circle_flag(true);
388
389                if(settings.get_value("circle.layer_region",value) && value=="1")
390                        set_layer_region_flag(true);
391                else
392                        set_layer_region_flag(false);
393
394                if(settings.get_value("circle.layer_outline",value) && value=="1")
395                        set_layer_outline_flag(true);
396                else
397                        set_layer_outline_flag(false);
398
399                if(settings.get_value("circle.layer_advanced_outline",value) && value=="1")
400                        set_layer_advanced_outline_flag(true);
401                else
402                        set_layer_advanced_outline_flag(false);
403
404                if(settings.get_value("circle.layer_curve_gradient",value) && value=="1")
405                        set_layer_curve_gradient_flag(true);
406                else
407                        set_layer_curve_gradient_flag(false);
408
409                if(settings.get_value("circle.layer_plant",value) && value=="1")
410                        set_layer_plant_flag(true);
411                else
412                        set_layer_plant_flag(false);
413
414                if(settings.get_value("circle.layer_link_origins",value) && value=="0")
415                        set_layer_link_origins_flag(false);
416                else
417                        set_layer_link_origins_flag(true);
418
419                if(settings.get_value("circle.layer_origins_at_center",value) && value=="0")
420                        set_layer_origins_at_center_flag(false);
421                else
422                        set_layer_origins_at_center_flag(true);
423
424  // determine layer flags
425        layer_circle_flag = get_layer_circle_flag();
426  layer_region_flag = get_layer_region_flag();
427  layer_outline_flag = get_layer_outline_flag();
428  layer_advanced_outline_flag = get_layer_outline_flag();
429  layer_curve_gradient_flag = get_layer_curve_gradient_flag();
430  layer_plant_flag = get_layer_plant_flag();
431
432        }
433        catch(...)
434        {
435                synfig::warning("State Circle: Caught exception when attempting to load settings.");
436        }
437}
438
439void
440StateCircle_Context::save_settings()
441{
442        try
443        {
444                synfig::ChangeLocale change_locale(LC_NUMERIC, "C");
445                settings.set_value("circle.id",get_id());
446                settings.set_value("circle.fallofftype",strprintf("%d",get_falloff()));
447                settings.set_value("circle.blend",strprintf("%d",get_blend()));
448                settings.set_value("circle.opacity",strprintf("%f",(float)get_opacity()));
449                settings.set_value("circle.bline_width", bline_width_dist.get_value().get_string());
450                settings.set_value("circle.feather", feather_dist.get_value().get_string());
451                settings.set_value("circle.number_of_bline_points",strprintf("%d",(int)(get_number_of_bline_points() + 0.5)));
452                settings.set_value("circle.bline_point_angle_offset",strprintf("%f",(float)get_bline_point_angle_offset()));
453                settings.set_value("circle.invert",get_invert()?"1":"0");
454                settings.set_value("circle.layer_circle",get_layer_circle_flag()?"1":"0");
455                settings.set_value("circle.layer_outline",get_layer_outline_flag()?"1":"0");
456                settings.set_value("circle.layer_advanced_outline",get_layer_advanced_outline_flag()?"1":"0");
457                settings.set_value("circle.layer_region",get_layer_region_flag()?"1":"0");
458                settings.set_value("circle.layer_curve_gradient",get_layer_curve_gradient_flag()?"1":"0");
459                settings.set_value("circle.layer_plant",get_layer_plant_flag()?"1":"0");
460                settings.set_value("circle.layer_link_origins",get_layer_link_origins_flag()?"1":"0");
461                settings.set_value("circle.layer_origins_at_center",get_layer_origins_at_center_flag()?"1":"0");
462        }
463        catch(...)
464        {
465                synfig::warning("State Circle: Caught exception when attempting to save settings.");
466        }
467}
468
469void
470StateCircle_Context::reset()
471{
472        refresh_ducks();
473}
474
475void
476StateCircle_Context::increment_id()
477{
478        String id(get_id());
479        int number=1;
480        int digits=0;
481
482        if(id.empty())
483                id="Circle";
484
485        // If there is a number
486        // already at the end of the
487        // id, then remove it.
488        if(id[id.size()-1]<='9' && id[id.size()-1]>='0')
489        {
490                // figure out how many digits it is
491                for (digits = 0;
492                         (int)id.size()-1 >= digits && id[id.size()-1-digits] <= '9' && id[id.size()-1-digits] >= '0';
493                         digits++)
494                        ;
495
496                String str_number;
497                str_number=String(id,id.size()-digits,id.size());
498                id=String(id,0,id.size()-digits);
499
500                number=atoi(str_number.c_str());
501        }
502        else
503        {
504                number=1;
505                digits=3;
506        }
507
508        number++;
509
510        // Add the number back onto the id
511        {
512                const String format(strprintf("%%0%dd",digits));
513                id+=strprintf(format.c_str(),number);
514        }
515
516        // Set the ID
517        set_id(id);
518}
519
520StateCircle_Context::StateCircle_Context(CanvasView* canvas_view):
521        canvas_view_(canvas_view),
522        is_working(*canvas_view),
523        duckmatic_push(get_work_area()),
524        prev_workarea_layer_status_(get_work_area()->get_allow_layer_clicks()),
525        settings(synfigapp::Main::get_selected_input_device()->settings()),
526        opacity_hscl(0.0f, 1.01f, 0.01f),
527        number_of_bline_points_adj(Gtk::Adjustment::create(0, 2, 120, 1, 1)),
528        number_of_bline_points_spin(number_of_bline_points_adj, 1, 0),
529        bline_point_angle_offset_adj(Gtk::Adjustment::create(0, -360, 360, 0.1, 1)),
530        bline_point_angle_offset_spin(bline_point_angle_offset_adj, 1, 1)
531{
532        egress_on_selection_change=true;
533
534
535        /* Set up the tool options dialog */
536
537        // 0, title
538        title_label.set_label(_("Circle Creation"));
539        Pango::AttrList list;
540        Pango::AttrInt attr = Pango::Attribute::create_attr_weight(Pango::WEIGHT_BOLD);
541        list.insert(attr);
542        title_label.set_attributes(list);
543        title_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
544
545        // 1, layer name label and entry
546        id_label.set_label(_("Name:"));
547        id_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
548        SPACING(id_gap, GAP);
549        id_box.pack_start(id_label, Gtk::PACK_SHRINK);
550        id_box.pack_start(*id_gap, Gtk::PACK_SHRINK);
551
552        id_box.pack_start(id_entry);
553
554        // 2, layer types creation
555        layer_types_label.set_label(_("Layer Type:"));
556        layer_types_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
557
558        LAYER_CREATION(layer_circle_togglebutton,
559                ("synfig-layer_geometry_circle"), _("Create a circle layer"));
560
561        LAYER_CREATION(layer_region_togglebutton,
562                ("synfig-layer_geometry_region"), _("Create a region layer"));
563
564        LAYER_CREATION(layer_outline_togglebutton,
565                ("synfig-layer_geometry_outline"), _("Create a outline layer"));
566
567        LAYER_CREATION(layer_advanced_outline_togglebutton,
568                ("synfig-layer_geometry_advanced_outline"), _("Create a advanced outline layer"));
569
570        LAYER_CREATION(layer_plant_togglebutton,
571                ("synfig-layer_other_plant"), _("Create a plant layer"));
572
573        LAYER_CREATION(layer_curve_gradient_togglebutton,
574                ("synfig-layer_gradient_curve"), _("Create a gradient layer"));
575
576        SPACING(layer_types_indent, INDENTATION);
577
578        layer_types_box.pack_start(*layer_types_indent, Gtk::PACK_SHRINK);
579        layer_types_box.pack_start(layer_circle_togglebutton, Gtk::PACK_SHRINK);
580        layer_types_box.pack_start(layer_region_togglebutton, Gtk::PACK_SHRINK);
581        layer_types_box.pack_start(layer_outline_togglebutton, Gtk::PACK_SHRINK);
582        layer_types_box.pack_start(layer_advanced_outline_togglebutton, Gtk::PACK_SHRINK);
583        layer_types_box.pack_start(layer_plant_togglebutton, Gtk::PACK_SHRINK);
584        layer_types_box.pack_start(layer_curve_gradient_togglebutton, Gtk::PACK_SHRINK);
585
586        // 3, blend method label and dropdown list
587        blend_label.set_label(_("Blend Method:"));
588        blend_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
589        SPACING(blend_gap, GAP);
590        blend_box.pack_start(blend_label, Gtk::PACK_SHRINK);
591        blend_box.pack_start(*blend_gap, Gtk::PACK_SHRINK);
592
593        blend_enum.set_param_desc(ParamDesc(Color::BLEND_COMPOSITE,"blend_method")
594                .set_local_name(_("Blend Method"))
595                .set_description(_("Defines the blend method to be used for circles")));
596
597        // 4, opacity label and slider
598        opacity_label.set_label(_("Opacity:"));
599        opacity_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
600
601        opacity_hscl.set_digits(2);
602        opacity_hscl.set_value_pos(Gtk::POS_LEFT);
603        opacity_hscl.set_tooltip_text(_("Opacity"));
604
605        // 5, brush size
606        bline_width_label.set_label(_("Brush Size:"));
607        bline_width_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
608        bline_width_label.set_sensitive(false);
609
610        bline_width_dist.set_digits(2);
611        bline_width_dist.set_range(0,10000000);
612        bline_width_dist.set_sensitive(false);
613
614        // 6, spline points
615        bline_points_label.set_label(_("Spline Points:"));
616        bline_points_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
617        bline_points_label.set_sensitive(false);
618        number_of_bline_points_spin.set_sensitive(false);
619
620        // 7, spline point angle offset
621        bline_point_angle_offset_label.set_label(_("Offset:"));
622        bline_point_angle_offset_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
623        bline_point_angle_offset_label.set_sensitive(false);
624        bline_point_angle_offset_spin.set_sensitive(false);
625
626        SPACING(bline_point_angle_offset_indent, INDENTATION);
627        bline_point_angle_offset_box.pack_start(*bline_point_angle_offset_indent, Gtk::PACK_SHRINK);
628        bline_point_angle_offset_box.pack_start(bline_point_angle_offset_label, Gtk::PACK_SHRINK);
629
630        // 8, invert
631        invert_label.set_label(_("Invert"));
632        invert_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
633
634        invert_box.pack_start(invert_label);
635        invert_box.pack_end(invert_checkbutton, Gtk::PACK_SHRINK);
636        invert_box.set_sensitive(false);
637
638        // 9, feather
639        feather_label.set_label(_("Feather:"));
640        feather_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
641        feather_label.set_sensitive(false);
642
643        feather_dist.set_digits(2);
644        feather_dist.set_range(0,10000000);
645        feather_dist.set_sensitive(false);
646
647        // 10, feather falloff for circle layer
648        falloff_label.set_label(_("Falloff:"));
649        falloff_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
650        falloff_label.set_sensitive(false);
651        SPACING(falloff_indent, INDENTATION);
652        falloff_box.pack_start(*falloff_indent, Gtk::PACK_SHRINK);
653        falloff_box.pack_start(falloff_label, Gtk::PACK_SHRINK);
654
655        falloff_enum.set_param_desc(ParamDesc("falloff")
656                .set_local_name(_("Falloff"))
657                .set_description(_("Determines the falloff function for the feather"))
658                .set_hint("enum")
659                .add_enum_value(CIRCLE_INTERPOLATION_LINEAR,"linear",_("Linear"))
660                .add_enum_value(CIRCLE_SQUARED,"squared",_("Squared"))
661                .add_enum_value(CIRCLE_SQRT,"sqrt",_("Square Root"))
662                .add_enum_value(CIRCLE_SIGMOND,"sigmond",_("Sigmond"))
663                .add_enum_value(CIRCLE_COSINE,"cosine",_("Cosine")));
664        falloff_enum.set_sensitive(false);
665
666        // 11, link origins
667        link_origins_label.set_label(_("Link Origins"));
668        link_origins_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
669
670        link_origins_box.pack_start(link_origins_label);
671        link_origins_box.pack_end(layer_link_origins_checkbutton, Gtk::PACK_SHRINK);
672        link_origins_box.set_sensitive(false);
673
674        // 12, spline origins at center
675        origins_at_center_label.set_label(_("Spline Origins at Center"));
676        origins_at_center_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
677
678        origins_at_center_box.pack_start(origins_at_center_label);
679        origins_at_center_box.pack_end(layer_origins_at_center_checkbutton, Gtk::PACK_SHRINK);
680        origins_at_center_box.set_sensitive(false);
681
682
683        load_settings();
684
685
686        // pack all options to the options_table
687
688        // 0, title
689        options_table.attach(title_label,
690                0, 2, 0, 1, Gtk::FILL, Gtk::FILL, 0, 0
691                );
692        // 1, name
693        options_table.attach(id_box,
694                0, 2, 1, 2, Gtk::FILL, Gtk::FILL, 0, 0
695                );
696        // 2, layer types creation
697        options_table.attach(layer_types_label,
698                0, 2, 2, 3, Gtk::FILL, Gtk::FILL, 0, 0
699                );
700        options_table.attach(layer_types_box,
701                0, 2, 3, 4, Gtk::FILL, Gtk::FILL, 0, 0
702                );
703        // 3, blend method
704        options_table.attach(blend_box,
705                0, 1, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
706                );
707        options_table.attach(blend_enum,
708                1, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
709                );
710        // 4, opacity
711        options_table.attach(opacity_label,
712                0, 1, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
713                );
714        options_table.attach(opacity_hscl,
715                1, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
716                );
717        // 5, brush size
718        options_table.attach(bline_width_label,
719                0, 1, 6, 7, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
720                );
721        options_table.attach(bline_width_dist,
722                1, 2, 6, 7, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
723                );
724        // 6, spline points
725        options_table.attach(bline_points_label,
726                0, 1, 7, 8, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
727                );
728        options_table.attach(number_of_bline_points_spin,
729                1, 2, 7, 8, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
730                );
731        // 7, spline points offset
732        options_table.attach(bline_point_angle_offset_box,
733                0, 1, 8, 9, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
734                );
735        options_table.attach(bline_point_angle_offset_spin,
736                1, 2, 8, 9, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
737                );
738        // 8, invert
739        options_table.attach(invert_box,
740                0, 2, 9, 10, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
741                );
742        // 9, feather
743        options_table.attach(feather_label,
744                0, 1, 10, 11, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
745                );
746        options_table.attach(feather_dist,
747                1, 2, 10, 11, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
748                );
749  // 10, falloff
750  options_table.attach(falloff_box,
751                0, 1, 11, 12, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
752                );
753        options_table.attach(falloff_enum,
754                1, 2, 11, 12, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
755                );
756        // 11, link origins
757        options_table.attach(link_origins_box,
758                0, 2, 12, 13, Gtk::FILL, Gtk::FILL, 0, 0
759                );
760        // 12, origins at center
761        options_table.attach(origins_at_center_box,
762                0, 2, 13, 14, Gtk::FILL, Gtk::FILL, 0, 0
763                );
764
765        // fine-tune options layout
766        options_table.set_border_width(GAP*2); // border width
767        options_table.set_row_spacings(GAP); // row gap
768        options_table.set_row_spacing(0, GAP*2); // the gap between first and second row.
769        options_table.set_row_spacing(2, 1); // row gap between label and icon of layer type
770        options_table.set_row_spacing(14, 0); // the final row using border width of table
771
772        options_table.show_all();
773
774        refresh_tool_options();
775        App::dialog_tool_options->present();
776
777        // Turn off layer clicking
778        get_work_area()->set_allow_layer_clicks(false);
779
780        // clear out the ducks
781        get_work_area()->clear_ducks();
782
783        // Refresh the work area
784        get_work_area()->queue_draw();
785
786        get_work_area()->set_cursor(Gdk::CROSSHAIR);
787
788        App::dock_toolbox->refresh();
789}
790
791void
792StateCircle_Context::refresh_tool_options()
793{
794        App::dialog_tool_options->clear();
795        App::dialog_tool_options->set_widget(options_table);
796        App::dialog_tool_options->set_local_name(_("Circle Tool"));
797        App::dialog_tool_options->set_name("circle");
798}
799
800Smach::event_result
801StateCircle_Context::event_refresh_tool_options(const Smach::event& /*x*/)
802{
803        refresh_tool_options();
804        return Smach::RESULT_ACCEPT;
805}
806
807StateCircle_Context::~StateCircle_Context()
808{
809        save_settings();
810
811        // Restore layer clicking
812        get_work_area()->set_allow_layer_clicks(prev_workarea_layer_status_);
813        get_work_area()->reset_cursor();
814
815        App::dialog_tool_options->clear();
816
817        // Refresh the work area
818        get_work_area()->queue_draw();
819
820        get_canvas_view()->queue_rebuild_ducks();
821
822        App::dock_toolbox->refresh();
823}
824
825Smach::event_result
826StateCircle_Context::event_stop_handler(const Smach::event& /*x*/)
827{
828        throw &state_normal;
829        return Smach::RESULT_OK;
830}
831
832Smach::event_result
833StateCircle_Context::event_refresh_handler(const Smach::event& /*x*/)
834{
835        refresh_ducks();
836        return Smach::RESULT_ACCEPT;
837}
838
839void
840StateCircle_Context::make_circle(const Point& _p1, const Point& _p2)
841{
842        synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("New Circle"));
843        synfigapp::PushMode push_mode(get_canvas_interface(),synfigapp::MODE_NORMAL);
844
845        Layer::Handle layer;
846
847        Canvas::Handle canvas;
848        int depth(0);
849
850        // we are temporarily using the layer to hold something
851        layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
852        if(layer)
853        {
854                depth=layer->get_depth();
855                canvas=layer->get_canvas();
856        }
857
858        synfigapp::SelectionManager::LayerList layer_selection;
859        if (!getenv("SYNFIG_TOOLS_CLEAR_SELECTION"))
860                layer_selection = get_canvas_view()->get_selection_manager()->get_selected_layers();
861
862        const synfig::TransformStack& transform(get_work_area()->get_curr_transform_stack());
863        const Point p1(transform.unperform(_p1));
864        const Point p2(transform.unperform(_p2));
865
866        Real radius((p2-p1).mag());
867        int points = get_number_of_bline_points();
868        Angle::deg offset(get_bline_point_angle_offset());
869        Angle::deg angle(360.0/points);
870        Real tangent(4 * ((points == 2)
871                                          ? 1
872                                          : ((2 * Angle::cos(angle/2).get() - Angle::cos(angle).get() - 1) / Angle::sin(angle).get())));
873        Vector origin;
874        Real x, y;
875
876        if (get_layer_origins_at_center_flag())
877        {
878                x = y = 0;
879                origin = p1;
880        }
881        else
882        {
883                x = p1[0];
884                y = p1[1];
885        }
886
887        std::vector<BLinePoint> new_list;
888        for (int i = 0; i < points; i++)
889        {
890                new_list.push_back(*(new BLinePoint));
891                new_list[i].set_width(1);
892                new_list[i].set_vertex(Point(radius*Angle::cos(angle*i + offset).get() + x,
893                                                                         radius*Angle::sin(angle*i + offset).get() + y));
894                new_list[i].set_tangent(Point(-radius*tangent*Angle::sin(angle*i + offset).get(),
895                                                                           radius*tangent*Angle::cos(angle*i + offset).get()));
896        }
897
898        ValueNode_BLine::Handle value_node_bline(ValueNode_BLine::create(new_list));
899        assert(value_node_bline);
900
901        ValueNode::Handle value_node_origin(ValueNode_Const::create(origin));
902        assert(value_node_origin);
903
904        // Set the looping flag
905        value_node_bline->set_loop(true);
906
907        if(!canvas)
908                canvas=get_canvas_view()->get_canvas();
909
910        value_node_bline->set_member_canvas(canvas);
911
912        // count how many layers we're going to be creating
913        int layers_to_create = this->layers_to_create();
914
915        ///////////////////////////////////////////////////////////////////////////
916        //   C I R C L E
917        ///////////////////////////////////////////////////////////////////////////
918
919        if (get_layer_circle_flag() &&
920                get_falloff() >= 0 && get_falloff() < CIRCLE_NUM_FALLOFF)
921        {
922                egress_on_selection_change=false;
923                layer=get_canvas_interface()->add_layer_to("circle",canvas,depth);
924                egress_on_selection_change=true;
925                if (!layer)
926                {
927                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
928                        group.cancel();
929                        return;
930                }
931                layer_selection.push_back(layer);
932
933                layer->set_param("radius",(p2-p1).mag());
934                get_canvas_interface()->signal_layer_param_changed()(layer,"radius");
935
936                layer->set_param("falloff",get_falloff());
937                get_canvas_interface()->signal_layer_param_changed()(layer,"falloff");
938
939                layer->set_param("amount",get_opacity());
940                get_canvas_interface()->signal_layer_param_changed()(layer,"amount");
941
942                layer->set_param("feather",get_feather_size());
943                get_canvas_interface()->signal_layer_param_changed()(layer,"feather");
944
945                layer->set_param("invert",get_invert());
946                get_canvas_interface()->signal_layer_param_changed()(layer,"invert");
947
948                layer->set_param("blend_method",get_blend());
949                get_canvas_interface()->signal_layer_param_changed()(layer,"blend_method");
950
951                layer->set_description(get_id());
952                get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
953
954                // only link the circle's origin parameter if the option is selected, we're putting bline
955                // origins at their centers, and we're creating more than one layer
956                if (get_layer_link_origins_flag() && get_layer_origins_at_center_flag() && layers_to_create > 1)
957                {
958                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
959                        assert(action);
960
961                        action->set_param("canvas",get_canvas());
962                        action->set_param("canvas_interface",get_canvas_interface());
963                        action->set_param("layer",layer);
964                        if(!action->set_param("param",String("origin")))
965                                synfig::error("LayerParamConnect didn't like \"param\"");
966                        if(!action->set_param("value_node",ValueNode::Handle(value_node_origin)))
967                                synfig::error("LayerParamConnect didn't like \"value_node\"");
968
969                        if(!get_canvas_interface()->get_instance()->perform_action(action))
970                        {
971                                group.cancel();
972                                throw String(_("Unable to create Circle layer"));
973                                return;
974                        }
975                }
976                else
977                {
978                        layer->set_param("origin",p1);
979                        get_canvas_interface()->signal_layer_param_changed()(layer,"origin");
980                }
981        }
982
983        ///////////////////////////////////////////////////////////////////////////
984        //   C U R V E   G R A D I E N T
985        ///////////////////////////////////////////////////////////////////////////
986
987        if(get_layer_curve_gradient_flag())
988        {
989                synfigapp::PushMode push_mode(get_canvas_interface(),synfigapp::MODE_NORMAL);
990
991                egress_on_selection_change=false;
992                Layer::Handle layer(get_canvas_interface()->add_layer_to("curve_gradient",canvas,depth));
993                egress_on_selection_change=true;
994                if (!layer)
995                {
996                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
997                        group.cancel();
998                        return;
999                }
1000                layer_selection.push_back(layer);
1001                layer->set_description(get_id()+_(" Gradient"));
1002                get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
1003
1004                layer->set_param("blend_method",get_blend());
1005                get_canvas_interface()->signal_layer_param_changed()(layer,"blend_method");
1006
1007                layer->set_param("amount",get_opacity());
1008                get_canvas_interface()->signal_layer_param_changed()(layer,"amount");
1009
1010                layer->set_param("width",get_bline_width());
1011                get_canvas_interface()->signal_layer_param_changed()(layer,"width");
1012
1013                {
1014                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1015                        assert(action);
1016
1017                        action->set_param("canvas",get_canvas());
1018                        action->set_param("canvas_interface",get_canvas_interface());
1019                        action->set_param("layer",layer);
1020                        if(!action->set_param("param",String("bline")))
1021                                synfig::error("LayerParamConnect didn't like \"param\"");
1022                        if(!action->set_param("value_node",ValueNode::Handle(value_node_bline)))
1023                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1024
1025                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1026                        {
1027                                group.cancel();
1028                                throw String(_("Unable to create Gradient layer"));
1029                                return;
1030                        }
1031                }
1032
1033                // only link the curve gradient's origin parameter if the option is selected and we're creating more than one layer
1034                if (get_layer_link_origins_flag() && layers_to_create > 1)
1035                {
1036                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1037                        assert(action);
1038
1039                        action->set_param("canvas",get_canvas());
1040                        action->set_param("canvas_interface",get_canvas_interface());
1041                        action->set_param("layer",layer);
1042                        if(!action->set_param("param",String("origin")))
1043                                synfig::error("LayerParamConnect didn't like \"param\"");
1044                        if(!action->set_param("value_node",ValueNode::Handle(value_node_origin)))
1045                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1046
1047                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1048                        {
1049                                group.cancel();
1050                                throw String(_("Unable to create Gradient layer"));
1051                                return;
1052                        }
1053                }
1054                else
1055                {
1056                        layer->set_param("origin",origin);
1057                        get_canvas_interface()->signal_layer_param_changed()(layer,"origin");
1058                }
1059        }
1060
1061        ///////////////////////////////////////////////////////////////////////////
1062        //   P L A N T
1063        ///////////////////////////////////////////////////////////////////////////
1064
1065        if(get_layer_plant_flag())
1066        {
1067                synfigapp::PushMode push_mode(get_canvas_interface(),synfigapp::MODE_NORMAL);
1068
1069                egress_on_selection_change=false;
1070                Layer::Handle layer(get_canvas_interface()->add_layer_to("plant",canvas,depth));
1071                egress_on_selection_change=true;
1072                if (!layer)
1073                {
1074                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
1075                        group.cancel();
1076                        return;
1077                }
1078                layer_selection.push_back(layer);
1079                layer->set_description(get_id()+_(" Plant"));
1080                get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
1081
1082                layer->set_param("blend_method",get_blend());
1083                get_canvas_interface()->signal_layer_param_changed()(layer,"blend_method");
1084
1085                layer->set_param("amount",get_opacity());
1086                get_canvas_interface()->signal_layer_param_changed()(layer,"amount");
1087
1088                {
1089                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1090                        assert(action);
1091
1092                        action->set_param("canvas",get_canvas());
1093                        action->set_param("canvas_interface",get_canvas_interface());
1094                        action->set_param("layer",layer);
1095                        if(!action->set_param("param",String("bline")))
1096                                synfig::error("LayerParamConnect didn't like \"param\"");
1097                        if(!action->set_param("value_node",ValueNode::Handle(value_node_bline)))
1098                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1099
1100                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1101                        {
1102                                group.cancel();
1103                                throw String(_("Unable to create Plant layer"));
1104                                return;
1105                        }
1106                }
1107
1108                // only link the plant's origin parameter if the option is selected and we're creating more than one layer
1109                if (get_layer_link_origins_flag() && layers_to_create > 1)
1110                {
1111                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1112                        assert(action);
1113
1114                        action->set_param("canvas",get_canvas());
1115                        action->set_param("canvas_interface",get_canvas_interface());
1116                        action->set_param("layer",layer);
1117                        if(!action->set_param("param",String("origin")))
1118                                synfig::error("LayerParamConnect didn't like \"param\"");
1119                        if(!action->set_param("value_node",ValueNode::Handle(value_node_origin)))
1120                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1121
1122                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1123                        {
1124                                group.cancel();
1125                                throw String(_("Unable to create Plant layer"));
1126                                return;
1127                        }
1128                }
1129                else
1130                {
1131                        layer->set_param("origin",origin);
1132                        get_canvas_interface()->signal_layer_param_changed()(layer,"origin");
1133                }
1134        }
1135
1136        ///////////////////////////////////////////////////////////////////////////
1137        //   R E G I O N
1138        ///////////////////////////////////////////////////////////////////////////
1139
1140        if(get_layer_region_flag())
1141        {
1142                synfigapp::PushMode push_mode(get_canvas_interface(),synfigapp::MODE_NORMAL);
1143
1144                egress_on_selection_change=false;
1145                Layer::Handle layer(get_canvas_interface()->add_layer_to("region",canvas,depth));
1146                egress_on_selection_change=true;
1147                if (!layer)
1148                {
1149                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
1150                        group.cancel();
1151                        return;
1152                }
1153                layer_selection.push_back(layer);
1154                layer->set_description(get_id()+_(" Region"));
1155                get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
1156
1157                layer->set_param("blend_method",get_blend());
1158                get_canvas_interface()->signal_layer_param_changed()(layer,"blend_method");
1159
1160                layer->set_param("amount",get_opacity());
1161                get_canvas_interface()->signal_layer_param_changed()(layer,"amount");
1162
1163                layer->set_param("feather",get_feather_size());
1164                get_canvas_interface()->signal_layer_param_changed()(layer,"feather");
1165
1166                layer->set_param("invert",get_invert());
1167                get_canvas_interface()->signal_layer_param_changed()(layer,"invert");
1168
1169                // I don't know if it's safe to reuse the same LayerParamConnect action, so I'm
1170                // using 2 separate ones.
1171                {
1172                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1173                        assert(action);
1174
1175                        action->set_param("canvas",get_canvas());
1176                        action->set_param("canvas_interface",get_canvas_interface());
1177                        action->set_param("layer",layer);
1178                        if(!action->set_param("param",String("bline")))
1179                                synfig::error("LayerParamConnect didn't like \"param\"");
1180                        if(!action->set_param("value_node",ValueNode::Handle(value_node_bline)))
1181                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1182
1183                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1184                        {
1185                                //get_canvas_view()->get_ui_interface()->error(_("Unable to create Region layer"));
1186                                group.cancel();
1187                                throw String(_("Unable to create Region layer"));
1188                                return;
1189                        }
1190                }
1191
1192                // only link the region's origin parameter if the option is selected and we're creating more than one layer
1193                if (get_layer_link_origins_flag() && layers_to_create > 1)
1194                {
1195                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1196                        assert(action);
1197
1198                        action->set_param("canvas",get_canvas());
1199                        action->set_param("canvas_interface",get_canvas_interface());
1200                        action->set_param("layer",layer);
1201                        if(!action->set_param("param",String("origin")))
1202                                synfig::error("LayerParamConnect didn't like \"param\"");
1203                        if(!action->set_param("value_node",ValueNode::Handle(value_node_origin)))
1204                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1205
1206                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1207                        {
1208                                //get_canvas_view()->get_ui_interface()->error(_("Unable to create Region layer"));
1209                                group.cancel();
1210                                throw String(_("Unable to create Region layer"));
1211                                return;
1212                        }
1213                }
1214                else
1215                {
1216                        layer->set_param("origin",origin);
1217                        get_canvas_interface()->signal_layer_param_changed()(layer,"origin");
1218                }
1219        }
1220
1221        ///////////////////////////////////////////////////////////////////////////
1222        //   O U T L I N E
1223        ///////////////////////////////////////////////////////////////////////////
1224
1225        if (get_layer_outline_flag())
1226        {
1227                egress_on_selection_change=false;
1228                Layer::Handle layer(get_canvas_interface()->add_layer_to("outline",canvas,depth));
1229                egress_on_selection_change=true;
1230                if (!layer)
1231                {
1232                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
1233                        group.cancel();
1234                        return;
1235                }
1236                layer_selection.push_back(layer);
1237                layer->set_description(get_id()+_(" Outline"));
1238                get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
1239
1240                layer->set_param("blend_method",get_blend());
1241                get_canvas_interface()->signal_layer_param_changed()(layer,"blend_method");
1242
1243                layer->set_param("amount",get_opacity());
1244                get_canvas_interface()->signal_layer_param_changed()(layer,"amount");
1245
1246                layer->set_param("width",get_bline_width());
1247                get_canvas_interface()->signal_layer_param_changed()(layer,"width");
1248
1249                layer->set_param("feather",get_feather_size());
1250                get_canvas_interface()->signal_layer_param_changed()(layer,"feather");
1251
1252                layer->set_param("invert",get_invert());
1253                get_canvas_interface()->signal_layer_param_changed()(layer,"invert");
1254
1255                {
1256                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1257                        assert(action);
1258
1259                        action->set_param("canvas",get_canvas());
1260                        action->set_param("canvas_interface",get_canvas_interface());
1261                        action->set_param("layer",layer);
1262                        if(!action->set_param("param",String("bline")))
1263                                synfig::error("LayerParamConnect didn't like \"param\"");
1264                        if(!action->set_param("value_node",ValueNode::Handle(value_node_bline)))
1265                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1266
1267                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1268                        {
1269                                group.cancel();
1270                                throw String(_("Unable to create Outline layer"));
1271                                return;
1272                        }
1273                }
1274
1275                // only link the outline's origin parameter if the option is selected and we're creating more than one layer
1276                if (get_layer_link_origins_flag() && layers_to_create > 1)
1277                {
1278                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1279                        assert(action);
1280
1281                        action->set_param("canvas",get_canvas());
1282                        action->set_param("canvas_interface",get_canvas_interface());
1283                        action->set_param("layer",layer);
1284                        if(!action->set_param("param",String("origin")))
1285                                synfig::error("LayerParamConnect didn't like \"param\"");
1286                        if(!action->set_param("value_node",ValueNode::Handle(value_node_origin)))
1287                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1288
1289                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1290                        {
1291                                group.cancel();
1292                                throw String(_("Unable to create Outline layer"));
1293                                return;
1294                        }
1295                }
1296                else
1297                {
1298                        layer->set_param("origin",origin);
1299                        get_canvas_interface()->signal_layer_param_changed()(layer,"origin");
1300                }
1301        }
1302
1303        ///////////////////////////////////////////////////////////////////////////
1304        //   A D V A N C E D   O U T L I N E
1305        ///////////////////////////////////////////////////////////////////////////
1306
1307        if (get_layer_advanced_outline_flag())
1308        {
1309                synfigapp::PushMode push_mode(get_canvas_interface(),synfigapp::MODE_NORMAL);
1310                egress_on_selection_change=false;
1311                Layer::Handle layer(get_canvas_interface()->add_layer_to("advanced_outline",canvas,depth));
1312                egress_on_selection_change=true;
1313                if (!layer)
1314                {
1315                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
1316                        group.cancel();
1317                        return;
1318                }
1319                layer_selection.push_back(layer);
1320                layer->set_description(get_id()+_(" Advanced Outline"));
1321                get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
1322
1323                layer->set_param("blend_method",get_blend());
1324                get_canvas_interface()->signal_layer_param_changed()(layer,"blend_method");
1325
1326                layer->set_param("amount",get_opacity());
1327                get_canvas_interface()->signal_layer_param_changed()(layer,"amount");
1328
1329                layer->set_param("width",get_bline_width());
1330                get_canvas_interface()->signal_layer_param_changed()(layer,"width");
1331
1332                layer->set_param("feather",get_feather_size());
1333                get_canvas_interface()->signal_layer_param_changed()(layer,"feather");
1334
1335                layer->set_param("invert",get_invert());
1336                get_canvas_interface()->signal_layer_param_changed()(layer,"invert");
1337
1338                {
1339                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1340                        assert(action);
1341
1342                        action->set_param("canvas",get_canvas());
1343                        action->set_param("canvas_interface",get_canvas_interface());
1344                        action->set_param("layer",layer);
1345                        if(!action->set_param("param",String("bline")))
1346                                synfig::error("LayerParamConnect didn't like \"param\"");
1347                        if(!action->set_param("value_node",ValueNode::Handle(value_node_bline)))
1348                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1349
1350                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1351                        {
1352                                group.cancel();
1353                                throw String(_("Unable to create Advanced Outline layer"));
1354                                return;
1355                        }
1356                }
1357
1358                // only link the outline's origin parameter if the option is selected and we're creating more than one layer
1359                if (get_layer_link_origins_flag() && layers_to_create > 1)
1360                {
1361                        synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));
1362                        assert(action);
1363
1364                        action->set_param("canvas",get_canvas());
1365                        action->set_param("canvas_interface",get_canvas_interface());
1366                        action->set_param("layer",layer);
1367                        if(!action->set_param("param",String("origin")))
1368                                synfig::error("LayerParamConnect didn't like \"param\"");
1369                        if(!action->set_param("value_node",ValueNode::Handle(value_node_origin)))
1370                                synfig::error("LayerParamConnect didn't like \"value_node\"");
1371
1372                        if(!get_canvas_interface()->get_instance()->perform_action(action))
1373                        {
1374                                group.cancel();
1375                                throw String(_("Unable to create Advanced Outline layer"));
1376                                return;
1377                        }
1378                }
1379                else
1380                {
1381                        layer->set_param("origin",origin);
1382                        get_canvas_interface()->signal_layer_param_changed()(layer,"origin");
1383                }
1384        }
1385
1386        egress_on_selection_change=false;
1387        get_canvas_interface()->get_selection_manager()->clear_selected_layers();
1388        get_canvas_interface()->get_selection_manager()->set_selected_layers(layer_selection);
1389        egress_on_selection_change=true;
1390
1391        reset();
1392        increment_id();
1393}
1394
1395Smach::event_result
1396StateCircle_Context::event_mouse_click_handler(const Smach::event& x)
1397{
1398        const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
1399
1400        if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DOWN && event.button==BUTTON_LEFT)
1401        {
1402                point_holder=get_work_area()->snap_point_to_grid(event.pos);
1403                etl::handle<Duck> duck=new Duck();
1404                duck->set_point(point_holder);
1405                duck->set_name("p1");
1406                duck->set_type(Duck::TYPE_POSITION);
1407                duck->set_editable(false);
1408                get_work_area()->add_duck(duck);
1409
1410                point2_duck=new Duck();
1411                point2_duck->set_point(Vector(0,0));
1412                point2_duck->set_name("radius");
1413                point2_duck->set_origin(duck);
1414                point2_duck->set_radius(true);
1415                point2_duck->set_scalar(-1);
1416                point2_duck->set_type(Duck::TYPE_RADIUS);
1417                point2_duck->set_hover(true);
1418                get_work_area()->add_duck(point2_duck);
1419
1420                return Smach::RESULT_ACCEPT;
1421        }
1422
1423        if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DRAG && event.button==BUTTON_LEFT)
1424        {
1425                if (!point2_duck) return Smach::RESULT_OK;
1426                point2_duck->set_point(point_holder-get_work_area()->snap_point_to_grid(event.pos));
1427                get_work_area()->queue_draw();
1428                return Smach::RESULT_ACCEPT;
1429        }
1430
1431        if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_UP && event.button==BUTTON_LEFT)
1432        {
1433                Point point(get_work_area()->snap_point_to_grid(event.pos));
1434
1435                if (App::restrict_radius_ducks)
1436                {
1437                        if ((point[0] - point_holder[0]) < 0) point[0] = point_holder[0];
1438                        if ((point[1] - point_holder[1]) < 0) point[1] = point_holder[1];
1439                }
1440
1441                if (point_holder != point)
1442                        make_circle(point_holder, point);
1443                get_work_area()->clear_ducks();
1444                return Smach::RESULT_ACCEPT;
1445        }
1446
1447        return Smach::RESULT_OK;
1448}
1449
1450
1451void
1452StateCircle_Context::refresh_ducks()
1453{
1454        get_work_area()->clear_ducks();
1455        get_work_area()->queue_draw();
1456}
1457
1458
1459void
1460StateCircle_Context::toggle_layer_creation()
1461{
1462  // don't allow none layer creation
1463  if (get_layer_circle_flag() +
1464     get_layer_region_flag() +
1465     get_layer_outline_flag() +
1466     get_layer_advanced_outline_flag() +
1467     get_layer_curve_gradient_flag() +
1468     get_layer_plant_flag() == 0)
1469  {
1470    if(layer_circle_flag) set_layer_circle_flag(true);
1471    else if(layer_region_flag) set_layer_region_flag(true);
1472    else if(layer_outline_flag) set_layer_outline_flag(true);
1473    else if(layer_advanced_outline_flag) set_layer_advanced_outline_flag(true);
1474    else if(layer_curve_gradient_flag) set_layer_curve_gradient_flag(true);
1475    else if(layer_plant_flag) set_layer_plant_flag(true);
1476  }
1477
1478        // brush size
1479        if (get_layer_outline_flag() ||
1480                get_layer_advanced_outline_flag() ||
1481                get_layer_curve_gradient_flag())
1482        {
1483                bline_width_label.set_sensitive(true);
1484                bline_width_dist.set_sensitive(true);
1485        }
1486        else
1487        {
1488                bline_width_label.set_sensitive(false);
1489                bline_width_dist.set_sensitive(false);
1490        }
1491
1492        // spline points and offset angle
1493        if (!get_layer_region_flag() &&
1494                !get_layer_outline_flag() &&
1495                !get_layer_advanced_outline_flag() &&
1496                !get_layer_plant_flag() &&
1497                !get_layer_curve_gradient_flag())
1498        {
1499                bline_points_label.set_sensitive(false);
1500                number_of_bline_points_spin.set_sensitive(false);
1501                bline_point_angle_offset_label.set_sensitive(false);
1502                bline_point_angle_offset_spin.set_sensitive(false);
1503        }
1504        else
1505        {
1506                bline_points_label.set_sensitive(true);
1507                number_of_bline_points_spin.set_sensitive(true);
1508                bline_point_angle_offset_label.set_sensitive(true);
1509                bline_point_angle_offset_spin.set_sensitive(true);
1510        }
1511
1512        // invert
1513        if (get_layer_circle_flag() ||
1514                get_layer_region_flag() ||
1515                get_layer_outline_flag() ||
1516                get_layer_advanced_outline_flag())
1517        {
1518                invert_box.set_sensitive(true);
1519        }
1520        else
1521                invert_box.set_sensitive(false);
1522
1523        // feather size
1524        if (get_layer_circle_flag() ||
1525                get_layer_circle_flag() ||
1526                get_layer_region_flag() ||
1527                get_layer_outline_flag() ||
1528                get_layer_advanced_outline_flag())
1529        {
1530                feather_label.set_sensitive(true);
1531                feather_dist.set_sensitive(true);
1532        }
1533        else
1534        {
1535                feather_label.set_sensitive(false);
1536                feather_dist.set_sensitive(false);
1537        }
1538
1539        // falloff type for circle layer only
1540        if (get_layer_circle_flag())
1541        {
1542                feather_dist.set_sensitive(true);
1543                feather_label.set_sensitive(true);
1544
1545                falloff_label.set_sensitive(true);
1546                falloff_enum.set_sensitive(true);
1547        }
1548        else
1549        {
1550                falloff_label.set_sensitive(false);
1551                falloff_enum.set_sensitive(false);
1552        }
1553
1554        // orignis at center
1555        if (get_layer_region_flag() ||
1556                get_layer_outline_flag() ||
1557                get_layer_advanced_outline_flag() ||
1558                get_layer_plant_flag() ||
1559                get_layer_curve_gradient_flag())
1560        {
1561                origins_at_center_box.set_sensitive(true);
1562        }
1563        else
1564                origins_at_center_box.set_sensitive(false);
1565
1566        // link origins
1567        if (get_layer_region_flag() +
1568                get_layer_outline_flag() +
1569                get_layer_advanced_outline_flag() +
1570                get_layer_plant_flag() +
1571                get_layer_curve_gradient_flag() +
1572                get_layer_circle_flag() >= 2)
1573                {
1574                        link_origins_box.set_sensitive(true);
1575                }
1576        else link_origins_box.set_sensitive(false);
1577
1578  // update layer flags
1579  layer_circle_flag = get_layer_circle_flag();
1580  layer_region_flag = get_layer_region_flag();
1581  layer_outline_flag = get_layer_outline_flag();
1582  layer_advanced_outline_flag = get_layer_advanced_outline_flag();
1583  layer_curve_gradient_flag = get_layer_curve_gradient_flag();
1584  layer_plant_flag = get_layer_plant_flag();
1585}
Note: See TracBrowser for help on using the repository browser.