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

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

First release to xenial

File size: 24.7 KB
Line 
1/* === S Y N F I G ========================================================= */
2/*!     \file state_gradient.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**  Copyright (c) 2010 Carlos López
11**
12**      This package is free software; you can redistribute it and/or
13**      modify it under the terms of the GNU General Public License as
14**      published by the Free Software Foundation; either version 2 of
15**      the License, or (at your option) any later version.
16**
17**      This package is distributed in the hope that it will be useful,
18**      but WITHOUT ANY WARRANTY; without even the implied warranty of
19**      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20**      General Public License for more details.
21**      \endlegal
22*/
23/* ========================================================================= */
24
25/* === H E A D E R S ======================================================= */
26
27#ifdef USING_PCH
28#       include "pch.h"
29#else
30#ifdef HAVE_CONFIG_H
31#       include <config.h>
32#endif
33
34#include <synfig/valuenodes/valuenode_dynamiclist.h>
35#include <synfigapp/action_system.h>
36
37#include "state_gradient.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
50#include "widgets/widget_enum.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 ========================================================= */
65
66#ifndef LAYER_CREATION
67#define LAYER_CREATION(button, fun, stockid, tooltip)   \
68        { \
69                Gtk::Image *icon = manage(new Gtk::Image(Gtk::StockID(stockid), \
70                        Gtk::ICON_SIZE_SMALL_TOOLBAR)); \
71                button.add(*icon); \
72        } \
73        button.set_relief(Gtk::RELIEF_NONE); \
74        button.set_tooltip_text(tooltip); \
75        button.signal_toggled().connect(sigc::mem_fun(*this, \
76                &studio::StateGradient_Context::fun))
77#endif
78
79// indentation for options layout
80#ifndef SPACING
81#define SPACING(name, px) \
82        Gtk::Alignment *name = Gtk::manage(new Gtk::Alignment()); \
83        name->set_size_request(px)
84#endif
85
86#define GAP     (3)
87#define INDENTATION (6)
88
89/* === G L O B A L S ======================================================= */
90
91StateGradient studio::state_gradient;
92
93/* === C L A S S E S & S T R U C T S ======================================= */
94
95class studio::StateGradient_Context : public sigc::trackable
96{
97        etl::handle<CanvasView> canvas_view_;
98        CanvasView::IsWorking is_working;
99
100        Duckmatic::Push duckmatic_push;
101
102        synfigapp::Settings& settings;
103
104        Point point_holder;
105
106        etl::handle<Duck> point2_duck;
107
108        void refresh_ducks();
109
110        bool prev_workarea_layer_status_;
111
112        // holder of options
113        Gtk::Table options_table;
114
115        // title
116        Gtk::Label title_label;
117
118        // layer name:
119        Gtk::Label id_label;
120        Gtk::HBox id_box;
121        Gtk::Entry id_entry;
122
123        // layer types to create:
124        Gtk::Label layer_types_label;
125        Gtk::ToggleButton layer_circle_togglebutton;
126        Gtk::ToggleButton layer_linear_gradient_togglebutton;
127        Gtk::ToggleButton layer_radial_gradient_togglebutton;
128        Gtk::ToggleButton layer_conical_gradient_togglebutton;
129        Gtk::ToggleButton layer_spiral_gradient_togglebutton;
130        Gtk::HBox layer_types_box;
131
132        // blend method
133        Gtk::Label blend_label;
134        Gtk::HBox blend_box;
135        Widget_Enum blend_enum;
136
137        // opacity
138        Gtk::Label opacity_label;
139        Gtk::HScale opacity_hscl;
140
141
142public:
143        synfig::String get_id()const { return id_entry.get_text(); }
144        void set_id(const synfig::String& x) { return id_entry.set_text(x); }
145
146        int get_blend()const { return blend_enum.get_value(); }
147        void set_blend(int x) { return blend_enum.set_value(x); }
148
149        Real get_opacity()const { return opacity_hscl.get_value(); }
150        void set_opacity(Real x) { opacity_hscl.set_value(x); }
151
152        Smach::event_result event_stop_handler(const Smach::event& x);
153
154        Smach::event_result event_refresh_handler(const Smach::event& x);
155
156        Smach::event_result event_mouse_click_handler(const Smach::event& x);
157        Smach::event_result event_refresh_tool_options(const Smach::event& x);
158
159        bool get_layer_linear_gradient_flag()const
160        {
161                return layer_linear_gradient_togglebutton.get_active();
162        }
163        void set_layer_linear_gradient_flag(bool x)
164        {
165                return layer_linear_gradient_togglebutton.set_active(x);
166        }
167
168        bool get_layer_radial_gradient_flag()const
169        {
170                return layer_radial_gradient_togglebutton.get_active();
171        }
172        void set_layer_radial_gradient_flag(bool x)
173        {
174                return layer_radial_gradient_togglebutton.set_active(x);
175        }
176
177        bool get_layer_conical_gradient_flag()const
178        {
179                return layer_conical_gradient_togglebutton.get_active();
180        }
181        void set_layer_conical_gradient_flag(bool x)
182        {
183                return layer_conical_gradient_togglebutton.set_active(x);
184        }
185
186        bool get_layer_spiral_gradient_flag()const
187        {
188                return layer_spiral_gradient_togglebutton.get_active();
189        }
190        void set_layer_spiral_gradient_flag(bool x)
191        {
192                return layer_spiral_gradient_togglebutton.set_active(x);
193        }
194
195  bool layer_linear_gradient_flag;
196  bool layer_radial_gradient_flag;
197  bool layer_conical_gradient_flag;
198  bool layer_spiral_gradient_flag;
199
200        void refresh_tool_options();
201
202        StateGradient_Context(CanvasView* canvas_view);
203
204        ~StateGradient_Context();
205
206        const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
207        etl::handle<synfigapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
208        synfig::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
209        WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
210
211        //void on_user_click(synfig::Point point);
212        void load_settings();
213        void save_settings();
214        void reset();
215        void increment_id();
216
217        void make_gradient(const Point& p1, const Point& p2);
218        bool egress_on_selection_change;
219        Smach::event_result event_layer_selection_changed_handler(const Smach::event& /*x*/)
220        {
221                if(egress_on_selection_change)
222                        throw &state_normal; //throw Smach::egress_exception();
223                return Smach::RESULT_OK;
224        }
225
226        void toggle_layer_linear_gradient();
227        void toggle_layer_radial_gradient();
228        void toggle_layer_conical_gradient();
229        void toggle_layer_spiral_gradient();
230
231
232};      // END of class StateGradient_Context
233
234/* === M E T H O D S ======================================================= */
235
236StateGradient::StateGradient():
237        Smach::state<StateGradient_Context>("gradient")
238{
239        insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StateGradient_Context::event_layer_selection_changed_handler));
240        insert(event_def(EVENT_STOP,&StateGradient_Context::event_stop_handler));
241        insert(event_def(EVENT_TABLES_SHOW,&StateGradient_Context::event_stop_handler));
242        insert(event_def(EVENT_REFRESH,&StateGradient_Context::event_refresh_handler));
243        insert(event_def(EVENT_REFRESH_DUCKS,&StateGradient_Context::event_refresh_handler));
244        insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateGradient_Context::event_mouse_click_handler));
245        insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateGradient_Context::event_mouse_click_handler));
246        insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateGradient_Context::event_mouse_click_handler));
247        insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateGradient_Context::event_refresh_tool_options));
248}
249
250StateGradient::~StateGradient()
251{
252}
253
254void
255StateGradient_Context::load_settings()
256{
257        try
258        {
259                synfig::ChangeLocale change_locale(LC_NUMERIC, "C");
260                String value;
261
262                if(settings.get_value("gradient.id",value))
263                        set_id(value);
264                else
265                        set_id("Gradient");
266
267                if(settings.get_value("gradient.layer_linear_gradient",value) && value=="0")
268                        set_layer_linear_gradient_flag(false);
269                else
270                        set_layer_linear_gradient_flag(true);
271
272                if(settings.get_value("gradient.layer_radial_gradient",value) && value=="0")
273                        set_layer_radial_gradient_flag(false);
274                else
275                        set_layer_radial_gradient_flag(true);
276
277                if(settings.get_value("gradient.layer_conical_gradient",value) && value=="0")
278                        set_layer_conical_gradient_flag(false);
279                else
280                        set_layer_conical_gradient_flag(true);
281
282                if(settings.get_value("gradient.layer_spiral_gradient",value) && value=="0")
283                        set_layer_spiral_gradient_flag(false);
284                else
285                        set_layer_spiral_gradient_flag(true);
286
287                if(settings.get_value("gradient.blend",value))
288                        set_blend(atoi(value.c_str()));
289                else
290                        set_blend(Color::BLEND_COMPOSITE);
291
292                if(settings.get_value("gradient.opacity",value))
293                        set_opacity(atof(value.c_str()));
294                else
295                        set_opacity(1);
296
297          // determine layer flags
298                layer_linear_gradient_flag = get_layer_linear_gradient_flag();
299          layer_radial_gradient_flag = get_layer_radial_gradient_flag();
300          layer_conical_gradient_flag = get_layer_conical_gradient_flag();
301          layer_spiral_gradient_flag = get_layer_spiral_gradient_flag();
302        }
303        catch(...)
304        {
305                synfig::warning("State Gradient: Caught exception when attempting to load settings.");
306        }
307}
308
309void
310StateGradient_Context::save_settings()
311{
312        try
313        {
314                synfig::ChangeLocale change_locale(LC_NUMERIC, "C");
315                settings.set_value("gradient.id",get_id().c_str());
316                settings.set_value("gradient.layer_linear_gradient",get_layer_linear_gradient_flag()?"1":"0");
317                settings.set_value("gradient.layer_radial_gradient",get_layer_radial_gradient_flag()?"1":"0");
318                settings.set_value("gradient.layer_conical_gradient",get_layer_conical_gradient_flag()?"1":"0");
319                settings.set_value("gradient.layer_spiral_gradient",get_layer_spiral_gradient_flag()?"1":"0");
320                settings.set_value("gradient.blend",strprintf("%d",get_blend()));
321                settings.set_value("gradient.opacity",strprintf("%f",(float)get_opacity()));
322        }
323        catch(...)
324        {
325                synfig::warning("State Gradient: Caught exception when attempting to save settings.");
326        }
327}
328
329void
330StateGradient_Context::reset()
331{
332        refresh_ducks();
333}
334
335void
336StateGradient_Context::increment_id()
337{
338        String id(get_id());
339        int number=1;
340        int digits=0;
341
342        if(id.empty())
343                id="Gradient";
344
345        // If there is a number
346        // already at the end of the
347        // id, then remove it.
348        if(id[id.size()-1]<='9' && id[id.size()-1]>='0')
349        {
350                // figure out how many digits it is
351                for (digits = 0;
352                         (int)id.size()-1 >= digits && id[id.size()-1-digits] <= '9' && id[id.size()-1-digits] >= '0';
353                         digits++)
354                        ;
355
356                String str_number;
357                str_number=String(id,id.size()-digits,id.size());
358                id=String(id,0,id.size()-digits);
359
360                number=atoi(str_number.c_str());
361        }
362        else
363        {
364                number=1;
365                digits=3;
366        }
367
368        number++;
369
370        // Add the number back onto the id
371        {
372                const String format(strprintf("%%0%dd",digits));
373                id+=strprintf(format.c_str(),number);
374        }
375
376        // Set the ID
377        set_id(id);
378}
379
380StateGradient_Context::StateGradient_Context(CanvasView* canvas_view):
381        canvas_view_(canvas_view),
382        is_working(*canvas_view),
383        duckmatic_push(get_work_area()),
384        settings(synfigapp::Main::get_selected_input_device()->settings()),
385        prev_workarea_layer_status_(get_work_area()->get_allow_layer_clicks()),
386        opacity_hscl(0.0f, 1.01f, 0.01f)
387
388{
389        egress_on_selection_change=true;
390
391        // Set up the tool options dialog
392
393        // title
394        title_label.set_label(_("Gradient Creation"));
395        Pango::AttrList list;
396        Pango::AttrInt attr = Pango::Attribute::create_attr_weight(Pango::WEIGHT_BOLD);
397        list.insert(attr);
398        title_label.set_attributes(list);
399        title_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
400
401        // layer name
402        id_label.set_label(_("Name:"));
403        SPACING(name_gap, GAP);
404        id_box.pack_start(id_label, Gtk::PACK_SHRINK);
405        id_box.pack_start(*name_gap, Gtk::PACK_SHRINK);
406        id_box.pack_start(id_entry, Gtk::PACK_EXPAND_WIDGET);
407
408        // layer (gradient) creation label
409        layer_types_label.set_label(_("Layer Type:"));
410        layer_types_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
411        // layer creation buttons
412        LAYER_CREATION(layer_linear_gradient_togglebutton, toggle_layer_linear_gradient,
413                ("synfig-layer_gradient_linear"), _("Create a linear gradient"));
414        LAYER_CREATION(layer_radial_gradient_togglebutton, toggle_layer_radial_gradient,
415                ("synfig-layer_gradient_radial"), _("Create a radial gradient"));
416        LAYER_CREATION(layer_conical_gradient_togglebutton, toggle_layer_conical_gradient,
417                ("synfig-layer_gradient_conical"), _("Create a conical gradient"));
418        LAYER_CREATION(layer_spiral_gradient_togglebutton, toggle_layer_spiral_gradient,
419                ("synfig-layer_gradient_spiral"), _("Create a spiral gradient"));
420
421        SPACING(layer_types_indent, INDENTATION);
422        layer_types_box.pack_start(*layer_types_indent, Gtk::PACK_SHRINK);
423        layer_types_box.pack_start(layer_linear_gradient_togglebutton, Gtk::PACK_SHRINK);
424        layer_types_box.pack_start(layer_radial_gradient_togglebutton, Gtk::PACK_SHRINK);
425        layer_types_box.pack_start(layer_conical_gradient_togglebutton, Gtk::PACK_SHRINK);
426        layer_types_box.pack_start(layer_spiral_gradient_togglebutton, Gtk::PACK_SHRINK);
427
428        // blend method label
429        blend_label.set_label(_("Blend Method:"));
430        blend_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
431        SPACING(blend_gap, GAP);
432        blend_box.pack_start(blend_label, Gtk::PACK_SHRINK);
433        blend_box.pack_start(*blend_gap, Gtk::PACK_SHRINK);
434        // blend method
435        blend_enum.set_param_desc(ParamDesc(Color::BLEND_COMPOSITE,"blend_method")
436                .set_local_name(_("Blend Method"))
437                .set_description(_("Defines the blend method to be used for gradients")));
438
439        // opacity label
440        opacity_label.set_label(_("Opacity:"));
441        opacity_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
442        // opacity
443        opacity_hscl.set_digits(2);
444        opacity_hscl.set_value_pos(Gtk::POS_LEFT);
445        opacity_hscl.set_tooltip_text(_("Opacity"));
446
447        // options table
448        // 0, title
449        options_table.attach(title_label,
450                0, 2,  0,  1, Gtk::FILL, Gtk::FILL, 0, 0
451                );
452        // 1, name
453        options_table.attach(id_box,
454                0, 2, 1, 2, Gtk::FILL, Gtk::FILL, 0, 0
455                );
456        // 2, layer types creation
457        options_table.attach(layer_types_label,
458                0, 2, 2, 3, Gtk::FILL, Gtk::FILL, 0, 0
459                );
460        options_table.attach(layer_types_box,
461                0, 2, 3, 4, Gtk::FILL, Gtk::FILL, 0, 0
462                );
463        // 3, blend method
464        options_table.attach(blend_box,
465                0, 1, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
466                );
467        options_table.attach(blend_enum,
468                1, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
469                );
470        // 4, opacity
471        options_table.attach(opacity_label,
472                0, 1, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
473                );
474        options_table.attach(opacity_hscl,
475                1, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0
476                );
477
478        // fine-tune options layout
479        options_table.set_border_width(GAP*2); // border width
480        options_table.set_row_spacings(GAP); // row gap
481        options_table.set_row_spacing(0, GAP*2); // the gap between first and second row.
482        options_table.set_row_spacing(2, 1); // row gap between label and icon of layer type
483        options_table.set_row_spacing(6, 0); // the final row using border width of table
484        options_table.show_all();
485
486        load_settings();
487        refresh_tool_options();
488        App::dialog_tool_options->present();
489
490
491        // Turn off layer clicking
492        get_work_area()->set_allow_layer_clicks(false);
493
494        get_work_area()->set_cursor(Gdk::CROSSHAIR);
495
496        // clear out the ducks
497        get_work_area()->clear_ducks();
498
499        // Refresh the work area
500        get_work_area()->queue_draw();
501
502        get_work_area()->refresh_cursor();
503
504        // Hide the tables if they are showing
505        get_canvas_view()->hide_tables();
506
507        // Disable the time bar
508        //get_canvas_view()->set_sensitive_timebar(false);
509
510        // Connect a signal
511        //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateGradient_Context::on_user_click));
512
513        App::dock_toolbox->refresh();
514}
515
516void
517StateGradient_Context::refresh_tool_options()
518{
519        App::dialog_tool_options->clear();
520        App::dialog_tool_options->set_widget(options_table);
521        App::dialog_tool_options->set_local_name(_("Gradient Tool"));
522        App::dialog_tool_options->set_name("gradient");
523}
524
525Smach::event_result
526StateGradient_Context::event_refresh_tool_options(const Smach::event& /*x*/)
527{
528        refresh_tool_options();
529        return Smach::RESULT_ACCEPT;
530}
531
532StateGradient_Context::~StateGradient_Context()
533{
534        save_settings();
535
536        // Restore layer clicking
537//      get_work_area()->set_allow_layer_clicks(prev_workarea_layer_status_);
538        get_work_area()->set_allow_layer_clicks(true);
539        get_work_area()->reset_cursor();
540
541        App::dialog_tool_options->clear();
542
543        // Enable the time bar
544        //get_canvas_view()->set_sensitive_timebar(true);
545
546        // Bring back the tables if they were out before
547        //if(prev_table_status)get_canvas_view()->show_tables();
548
549        // Refresh the work area
550        get_work_area()->queue_draw();
551
552        get_canvas_view()->queue_rebuild_ducks();
553
554        //get_canvas_view()->show_tables();
555
556        get_work_area()->refresh_cursor();
557
558        App::dock_toolbox->refresh();
559}
560
561Smach::event_result
562StateGradient_Context::event_stop_handler(const Smach::event& /*x*/)
563{
564        //throw Smach::egress_exception();
565        throw &state_normal;
566        return Smach::RESULT_OK;
567}
568
569Smach::event_result
570StateGradient_Context::event_refresh_handler(const Smach::event& /*x*/)
571{
572        refresh_ducks();
573        return Smach::RESULT_ACCEPT;
574}
575
576void
577StateGradient_Context::make_gradient(const Point& _p1, const Point& _p2)
578{
579        synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("New Gradient"));
580        synfigapp::PushMode push_mode(get_canvas_interface(),synfigapp::MODE_NORMAL);
581
582        Layer::Handle layer;
583
584        Canvas::Handle canvas(get_canvas_view()->get_canvas());
585        int depth(0);
586
587        // we are temporarily using the layer to hold something
588        layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
589        if(layer)
590        {
591                depth=layer->get_depth();
592                canvas=layer->get_canvas();
593        }
594        const synfig::TransformStack& transform(get_work_area()->get_curr_transform_stack());
595        const Point p1(transform.unperform(_p1));
596        const Point p2(transform.unperform(_p2));
597
598        if (get_layer_linear_gradient_flag())
599        {
600                egress_on_selection_change=false;
601                layer=get_canvas_interface()->add_layer_to("linear_gradient",canvas,depth);
602                egress_on_selection_change=true;
603                if (!layer)
604                {
605                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
606                        group.cancel();
607                        return;
608                }
609                layer->set_param("p1",p1);
610                get_canvas_interface()->signal_layer_param_changed()(layer,"p1");
611                layer->set_param("p2",p2);
612                get_canvas_interface()->signal_layer_param_changed()(layer,"p2");
613        }
614
615        else if (get_layer_radial_gradient_flag())
616        {
617                egress_on_selection_change=false;
618                layer=get_canvas_interface()->add_layer_to("radial_gradient",canvas,depth);
619                egress_on_selection_change=true;
620                if (!layer)
621                {
622                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
623                        group.cancel();
624                        return;
625                }
626                layer->set_param("center",p1);
627                get_canvas_interface()->signal_layer_param_changed()(layer,"center");
628                layer->set_param("radius",(p2-p1).mag());
629                get_canvas_interface()->signal_layer_param_changed()(layer,"radius");
630        }
631
632        else if (get_layer_conical_gradient_flag())
633        {
634                egress_on_selection_change=false;
635                layer=get_canvas_interface()->add_layer_to("conical_gradient",canvas,depth);
636                egress_on_selection_change=true;
637                if (!layer)
638                {
639                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
640                        group.cancel();
641                        return;
642                }
643                layer->set_param("center",p1);
644                get_canvas_interface()->signal_layer_param_changed()(layer,"center");
645                {
646                        Vector diff(p2-p1);
647                        layer->set_param("angle",Angle::tan(diff[1],diff[0]));
648                        get_canvas_interface()->signal_layer_param_changed()(layer,"angle");
649                }
650        }
651
652        else if (get_layer_spiral_gradient_flag())
653        {
654                egress_on_selection_change=false;
655                layer=get_canvas_interface()->add_layer_to("spiral_gradient",canvas,depth);
656                egress_on_selection_change=true;
657                if (!layer)
658                {
659                        get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
660                        group.cancel();
661                        return;
662                }
663                layer->set_param("center",p1);
664                get_canvas_interface()->signal_layer_param_changed()(layer,"center");
665                layer->set_param("radius",(p2-p1).mag());
666                get_canvas_interface()->signal_layer_param_changed()(layer,"radius");
667                {
668                        Vector diff(p2-p1);
669                        layer->set_param("angle",Angle::tan(diff[1],diff[0]));
670                        get_canvas_interface()->signal_layer_param_changed()(layer,"angle");
671                }
672        }
673        else return;
674
675        layer->set_param("blend_method", get_blend());
676        get_canvas_interface()->signal_layer_param_changed()(layer, "blend_method");
677
678        layer->set_param("amount", get_opacity());
679        get_canvas_interface()->signal_layer_param_changed()(layer, "amount");
680
681        layer->set_description(get_id());
682        get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
683
684        egress_on_selection_change=false;
685        synfigapp::SelectionManager::LayerList layer_selection;
686        if (!getenv("SYNFIG_TOOLS_CLEAR_SELECTION"))
687                layer_selection = get_canvas_view()->get_selection_manager()->get_selected_layers();
688        get_canvas_interface()->get_selection_manager()->clear_selected_layers();
689        layer_selection.push_back(layer);
690        get_canvas_interface()->get_selection_manager()->set_selected_layers(layer_selection);
691        egress_on_selection_change=true;
692
693        reset();
694        increment_id();
695}
696
697Smach::event_result
698StateGradient_Context::event_mouse_click_handler(const Smach::event& x)
699{
700        const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
701
702        if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DOWN && event.button==BUTTON_LEFT)
703        {
704                point_holder=get_work_area()->snap_point_to_grid(event.pos);
705                etl::handle<Duck> duck=new Duck();
706                duck->set_point(point_holder);
707                duck->set_name("p1");
708                duck->set_type(Duck::TYPE_POSITION);
709                get_work_area()->add_duck(duck);
710
711                point2_duck=new Duck();
712                point2_duck->set_point(point_holder);
713                point2_duck->set_name("p2");
714                point2_duck->set_type(Duck::TYPE_POSITION);
715                get_work_area()->add_duck(point2_duck);
716
717                handle<Duckmatic::Bezier> bezier(new Duckmatic::Bezier());
718                bezier->p1=bezier->c1=duck;
719                bezier->p2=bezier->c2=point2_duck;
720                get_work_area()->add_bezier(bezier);
721
722                return Smach::RESULT_ACCEPT;
723        }
724
725        if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DRAG && event.button==BUTTON_LEFT)
726        {
727                if (!point2_duck) return Smach::RESULT_OK;
728                point2_duck->set_point(get_work_area()->snap_point_to_grid(event.pos));
729                get_work_area()->queue_draw();
730                return Smach::RESULT_ACCEPT;
731        }
732
733        if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_UP && event.button==BUTTON_LEFT)
734        {
735                make_gradient(point_holder, get_work_area()->snap_point_to_grid(event.pos));
736                get_work_area()->clear_ducks();
737                return Smach::RESULT_ACCEPT;
738        }
739
740        return Smach::RESULT_OK;
741}
742
743
744void
745StateGradient_Context::refresh_ducks()
746{
747        get_work_area()->clear_ducks();
748        get_work_area()->queue_draw();
749}
750
751
752void
753StateGradient_Context::toggle_layer_linear_gradient()
754{
755        // enable linear gradient layer and disable the others
756        if(!layer_linear_gradient_flag)
757        {
758                set_layer_linear_gradient_flag(true);
759                set_layer_radial_gradient_flag(false);
760                set_layer_conical_gradient_flag(false);
761                set_layer_spiral_gradient_flag(false);
762
763                // update flags
764                layer_linear_gradient_flag = true;
765                layer_radial_gradient_flag = false;
766                layer_conical_gradient_flag = false;
767                layer_spiral_gradient_flag = false;
768        }
769
770        // don't allow to disable the enabled layer
771        if(get_layer_linear_gradient_flag() +
772                get_layer_radial_gradient_flag() +
773                get_layer_conical_gradient_flag() +
774                get_layer_spiral_gradient_flag() == 0
775                        ) set_layer_linear_gradient_flag(true);
776}
777
778
779void
780StateGradient_Context::toggle_layer_radial_gradient()
781{
782        // enable radial gradient layer and disable the others
783        if(!layer_radial_gradient_flag)
784        {
785                set_layer_linear_gradient_flag(false);
786                set_layer_radial_gradient_flag(true);
787                set_layer_spiral_gradient_flag(false);
788                set_layer_conical_gradient_flag(false);
789
790                // update flags
791                layer_linear_gradient_flag = false;
792                layer_radial_gradient_flag = true;
793                layer_conical_gradient_flag = false;
794                layer_spiral_gradient_flag = false;
795        }
796
797        // don't allow to disable the enabled layer
798        if(get_layer_linear_gradient_flag() +
799                get_layer_radial_gradient_flag() +
800                get_layer_conical_gradient_flag() +
801                get_layer_spiral_gradient_flag() == 0
802                        ) set_layer_radial_gradient_flag(true);
803}
804
805
806void
807StateGradient_Context::toggle_layer_conical_gradient()
808{
809        // enable conical gradient layer and disable the others
810        if(!layer_conical_gradient_flag)
811        {
812                set_layer_linear_gradient_flag(false);
813                set_layer_radial_gradient_flag(false);
814                set_layer_conical_gradient_flag(true);
815                set_layer_spiral_gradient_flag(false);
816
817                // update flags
818                layer_linear_gradient_flag = false;
819                layer_radial_gradient_flag = false;
820                layer_conical_gradient_flag = true;
821                layer_spiral_gradient_flag = false;
822        }
823
824        // don't allow to disable the enabled layer
825        if(get_layer_linear_gradient_flag() +
826                get_layer_radial_gradient_flag() +
827                get_layer_conical_gradient_flag() +
828                get_layer_spiral_gradient_flag() == 0
829                        ) set_layer_conical_gradient_flag(true);
830}
831
832
833void
834StateGradient_Context::toggle_layer_spiral_gradient()
835{
836        // enable spiral gradient layer and disable the others
837        if(!layer_spiral_gradient_flag)
838        {
839                set_layer_linear_gradient_flag(false);
840                set_layer_radial_gradient_flag(false);
841                set_layer_conical_gradient_flag(false);
842                set_layer_spiral_gradient_flag(true);
843
844                // update flags
845                layer_linear_gradient_flag = false;
846                layer_radial_gradient_flag = false;
847                layer_conical_gradient_flag = false;
848                layer_spiral_gradient_flag = true;
849        }
850
851        // don't allow to disable the enabled layer
852        if(get_layer_linear_gradient_flag() +
853                get_layer_radial_gradient_flag() +
854                get_layer_conical_gradient_flag() +
855                get_layer_spiral_gradient_flag() == 0
856                        ) set_layer_spiral_gradient_flag(true);
857}
Note: See TracBrowser for help on using the repository browser.