source: synfigstudio/trunk/fuentes/src/synfigapp/actions/layerfit.cpp @ 481

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

First release to xenial

File size: 5.1 KB
Line 
1/* === S Y N F I G ========================================================= */
2/*!     \file template.cpp
3**      \brief LayerFit
4**
5**      $Id$
6**
7**      \legal
8**      ......... ... 2013 Ivan Mahonin
9**
10**      This package is free software; you can redistribute it and/or
11**      modify it under the terms of the GNU General Public License as
12**      published by the Free Software Foundation; either version 2 of
13**      the License, or (at your option) any later version.
14**
15**      This package is distributed in the hope that it will be useful,
16**      but WITHOUT ANY WARRANTY; without even the implied warranty of
17**      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18**      General Public License for more details.
19**      \endlegal
20*/
21/* ========================================================================= */
22
23/* === H E A D E R S ======================================================= */
24
25#ifdef USING_PCH
26#       include "pch.h"
27#else
28#ifdef HAVE_CONFIG_H
29#       include <config.h>
30#endif
31
32#include "layerfit.h"
33#include <synfigapp/canvasinterface.h>
34#include <synfigapp/general.h>
35
36#endif
37
38/* === U S I N G =========================================================== */
39
40using namespace std;
41using namespace etl;
42using namespace synfig;
43using namespace synfigapp;
44using namespace Action;
45
46/* === M A C R O S ========================================================= */
47
48ACTION_INIT(Action::LayerFit);
49ACTION_SET_NAME(Action::LayerFit,"LayerFit");
50ACTION_SET_LOCAL_NAME(Action::LayerFit,N_("Fit image"));
51ACTION_SET_TASK(Action::LayerFit,"fit");
52ACTION_SET_CATEGORY(Action::LayerFit,Action::CATEGORY_LAYER);
53ACTION_SET_PRIORITY(Action::LayerFit,0);
54ACTION_SET_VERSION(Action::LayerFit,"0.0");
55ACTION_SET_CVS_ID(Action::LayerFit,"$Id$");
56
57/* === G L O B A L S ======================================================= */
58
59/* === P R O C E D U R E S ================================================= */
60
61/* === M E T H O D S ======================================================= */
62
63Action::LayerFit::LayerFit()
64{
65}
66
67Action::ParamVocab
68Action::LayerFit::get_param_vocab()
69{
70        ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
71
72        ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
73                .set_local_name(_("Layer"))
74        );
75
76        return ret;
77}
78
79bool
80Action::LayerFit::is_candidate(const ParamList &x)
81{
82        if (!candidate_check(get_param_vocab(),x))
83                return false;
84        for(ParamList::const_iterator i = x.begin(); i != x.end(); i++) {
85                if (i->first == "layer") {
86                        if (i->second.get_type() != Param::TYPE_LAYER) return false;
87                        const Layer::Handle layer = i->second.get_layer();
88                        if (layer.empty()
89                         || layer->get_param("tl").empty()
90                         || layer->get_param("br").empty())
91                                return false;
92                }
93        }
94        return true;
95}
96
97bool
98Action::LayerFit::set_param(const synfig::String& name, const Action::Param &param)
99{
100        if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
101        {
102                layer=param.get_layer();
103                return true;
104        }
105
106        return Action::CanvasSpecific::set_param(name,param);
107}
108
109bool
110Action::LayerFit::is_ready()const
111{
112        if(!layer)
113                return false;
114        return Action::CanvasSpecific::is_ready();
115}
116
117void
118Action::LayerFit::perform()
119{
120        Canvas::Handle subcanvas(layer->get_canvas());
121
122        // Find the iterator for the layer
123        Canvas::iterator iter=find(subcanvas->begin(),subcanvas->end(),layer);
124
125        // If we couldn't find the layer in the canvas, then bail
126        if(*iter!=layer)
127                throw Error(_("This layer doesn't exist anymore."));
128
129        if (layer->dynamic_param_list().count("tl") > 0
130         || layer->dynamic_param_list().count("br") > 0)
131                throw Error(_("You cannot fit animated layers"));
132
133        // remember values
134        prev_tl = layer->get_param("tl");
135        prev_br = layer->get_param("br");
136
137        set_dirty();
138
139        // new coordinates
140        Vector size = get_canvas()->rend_desc().get_br()-get_canvas()->rend_desc().get_tl();
141        ValueBase new_tl(Point(size*(-0.5f)));
142        ValueBase new_br(Point(size*0.5f));
143
144        // recalculate coordinates to keep proportions
145        int w = layer->get_param("_width").get(int());
146        int h = layer->get_param("_height").get(int());
147        if(w > 0 && h > 0)
148        {
149                Vector x;
150
151                if(abs(size[0])<abs(size[1]))   // if canvas is tall and thin
152                {
153                        x[0]=size[0];   // use full width
154                        x[1]=size[0]/w*h; // and scale for height
155                        if((size[0]<0) ^ (size[1]<0))
156                                x[1]=-x[1];
157                }
158                else                            // else canvas is short and fat (or maybe square)
159                {
160                        x[1]=size[1];   // use full height
161                        x[0]=size[1]/h*w; // and scale for width
162                        if((size[0]<0) ^ (size[1]<0))
163                                x[0]=-x[0];
164                }
165
166                new_tl = -x/2;
167                new_br = x/2;
168        }
169
170        layer->set_param("tl", new_tl);
171        layer->set_param("br", new_br);
172        layer->changed();
173
174        if(get_canvas_interface())
175        {
176                get_canvas_interface()->signal_layer_param_changed()(layer, "tl");
177                get_canvas_interface()->signal_layer_param_changed()(layer, "br");
178        }
179        else synfig::warning("CanvasInterface not set on action");
180}
181
182void
183Action::LayerFit::undo()
184{
185        set_dirty();
186
187        // restore the old state
188        layer->set_param("tl", prev_tl);
189        layer->set_param("br", prev_br);
190        layer->changed();
191
192        if(get_canvas_interface())
193        {
194                get_canvas_interface()->signal_layer_param_changed()(layer, "tl");
195                get_canvas_interface()->signal_layer_param_changed()(layer, "br");
196        }
197        else synfig::warning("CanvasInterface not set on action");
198}
199
200/* === E N T R Y P O I N T ================================================= */
201
202
Note: See TracBrowser for help on using the repository browser.