Build rectanglular blines in the same handedness as all the other shapes.
[synfig.git] / synfig-studio / trunk / src / synfigapp / main.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file synfigapp/main.cpp
3 **      \brief Template File
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
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 "main.h"
33 #include "action.h"
34
35 #include <synfig/color.h>
36 #include <synfig/gradient.h>
37
38 #include <ETL/trivial>
39
40 #include <list>
41
42 #include "general.h"
43
44 #endif
45
46 /* === U S I N G =========================================================== */
47
48 using namespace std;
49 using namespace etl;
50 using namespace synfig;
51 using namespace synfigapp;
52
53 /* === M A C R O S ========================================================= */
54
55 /* === S T A T I C S ======================================================= */
56
57 static etl::reference_counter synfigapp_ref_count_(0);
58 static synfigapp::Action::Main* action_main;
59
60 static Color foreground_;
61 static Color background_;
62 static Gradient gradient_;
63 static bool gradient_default_colors_;
64
65 static synfig::Distance bline_width_;
66
67 static Color::BlendMethod blend_method_;
68 static Real opacity_;
69
70 static synfigapp::InputDevice::Handle selected_input_device_;
71 static list<synfigapp::InputDevice::Handle> input_devices_;
72
73 trivial<sigc::signal<void> > signal_foreground_color_changed_;
74 trivial<sigc::signal<void> > signal_background_color_changed_;
75 trivial<sigc::signal<void> > signal_gradient_changed_;
76 trivial<sigc::signal<void> > signal_bline_width_changed_;
77 trivial<sigc::signal<void> > signal_blend_method_changed_;
78 trivial<sigc::signal<void> > signal_opacity_changed_;
79 trivial<sigc::signal<void> > signal_interpolation_changed_;
80
81 trivial<Settings> settings_;
82
83 static synfig::Waypoint::Interpolation interpolation_;
84
85 /* === P R O C E D U R E S ================================================= */
86
87 /* === M E T H O D S ======================================================= */
88
89 synfigapp::Main::Main(const synfig::String &basepath, synfig::ProgressCallback *cb):
90         synfig::Main(basepath,cb),
91         ref_count_(synfigapp_ref_count_)
92 {
93         if(ref_count_.count())
94                 return;
95
96         synfigapp_ref_count_.reset();
97         ref_count_=synfigapp_ref_count_;
98
99         // Add initialization after this point
100
101 #ifdef ENABLE_NLS
102         bindtextdomain("synfigstudio", LOCALEDIR);
103 #endif
104
105         action_main=new synfigapp::Action::Main();
106
107         settings_.construct();
108
109         signal_foreground_color_changed_.construct();
110         signal_background_color_changed_.construct();
111         signal_gradient_changed_.construct();
112         signal_opacity_changed_.construct();
113         signal_blend_method_changed_.construct();
114         signal_interpolation_changed_.construct();
115
116         set_foreground_color(Color::black());
117         set_background_color(Color::white());
118         set_gradient_default_colors();
119         set_bline_width(Distance(1,Distance::SYSTEM_POINTS));
120         set_opacity(1.0);
121         set_blend_method(Color::BLEND_COMPOSITE);
122 }
123
124 synfigapp::Main::~Main()
125 {
126         ref_count_.detach();
127         if(!synfigapp_ref_count_.unique())
128                 return;
129         synfigapp_ref_count_.detach();
130
131         // Add deinitialization after this point
132
133         delete action_main;
134
135         selected_input_device_=0;
136         input_devices_.clear();
137
138         settings_.destruct();
139         signal_foreground_color_changed_.destruct();
140         signal_background_color_changed_.destruct();
141         signal_gradient_changed_.destruct();
142
143         signal_opacity_changed_.destruct();
144         signal_blend_method_changed_.destruct();
145         signal_interpolation_changed_.destruct();
146 }
147
148 Settings&
149 synfigapp::Main::settings()
150 {
151         return settings_;
152 }
153
154 sigc::signal<void>&
155 synfigapp::Main::signal_foreground_color_changed()
156 {
157         return signal_foreground_color_changed_;
158 }
159
160 sigc::signal<void>&
161 synfigapp::Main::signal_background_color_changed()
162 {
163         return signal_background_color_changed_;
164 }
165
166 sigc::signal<void>&
167 synfigapp::Main::signal_gradient_changed()
168 {
169         return signal_gradient_changed_;
170 }
171
172 sigc::signal<void>&
173 synfigapp::Main::signal_bline_width_changed()
174 {
175         return signal_bline_width_changed_;
176 }
177
178 sigc::signal<void>&
179 synfigapp::Main::signal_blend_method_changed()
180 {
181         return signal_blend_method_changed_;
182 }
183
184 sigc::signal<void>&
185 synfigapp::Main::signal_opacity_changed()
186 {
187         return signal_opacity_changed_;
188 }
189
190 sigc::signal<void>&
191 synfigapp::Main::signal_interpolation_changed()
192 {
193         return signal_interpolation_changed_;
194 }
195
196 const synfig::Color&
197 synfigapp::Main::get_foreground_color()
198 {
199         return foreground_;
200 }
201
202 const synfig::Color&
203 synfigapp::Main::get_background_color()
204 {
205         return background_;
206 }
207
208 const synfig::Gradient&
209 synfigapp::Main::get_gradient()
210 {
211         return gradient_;
212 }
213
214 const synfig::Real&
215 synfigapp::Main::get_opacity()
216 {
217         return opacity_;
218 }
219
220 synfig::Color::BlendMethod
221 synfigapp::Main::get_blend_method()
222 {
223         return blend_method_;
224 }
225
226 void
227 synfigapp::Main::set_foreground_color(synfig::Color color)
228 {
229         foreground_=color;
230         signal_foreground_color_changed()();
231         if(selected_input_device_)
232                 selected_input_device_->set_foreground_color(foreground_);
233         if(gradient_default_colors_)
234         {
235                 gradient_=Gradient(foreground_,background_);
236                 signal_gradient_changed()();
237         }
238 }
239
240 void
241 synfigapp::Main::set_background_color(synfig::Color color)
242 {
243         background_=color;
244         signal_background_color_changed()();
245
246         if(selected_input_device_)
247                 selected_input_device_->set_background_color(background_);
248
249         if(gradient_default_colors_)
250         {
251                 gradient_=Gradient(foreground_,background_);
252                 signal_gradient_changed()();
253         }
254 }
255
256 void
257 synfigapp::Main::set_gradient(synfig::Gradient gradient)
258 {
259         gradient_=gradient;
260         gradient_default_colors_=false;
261         signal_gradient_changed()();
262 }
263
264 void
265 synfigapp::Main::set_gradient_default_colors()
266 {
267         gradient_default_colors_=true;
268         gradient_=Gradient(foreground_,background_);
269         signal_gradient_changed()();
270 }
271
272 void
273 synfigapp::Main::color_swap()
274 {
275         const Color tmp(foreground_);
276         foreground_=background_;
277         background_=tmp;
278
279         if(selected_input_device_)
280         {
281                 selected_input_device_->set_foreground_color(foreground_);
282                 selected_input_device_->set_background_color(background_);
283         }
284
285         signal_foreground_color_changed()();
286         signal_background_color_changed()();
287
288         if(gradient_default_colors_)
289         {
290                 gradient_=Gradient(foreground_,background_);
291                 signal_gradient_changed()();
292         }
293 }
294
295 synfig::Waypoint::Interpolation
296 synfigapp::Main::get_interpolation()
297 {
298         return interpolation_;
299 }
300
301
302 void
303 synfigapp::Main::set_interpolation(synfig::Waypoint::Interpolation x)
304 {
305         if(interpolation_!=x)
306         {
307                 interpolation_=x;
308
309                 signal_interpolation_changed();
310         }
311 }
312
313 const synfig::Distance&
314 synfigapp::Main::get_bline_width()
315 {
316         return bline_width_;
317 }
318
319 void
320 synfigapp::Main::set_bline_width(synfig::Distance x)
321 {
322         if(x<0)x=0;
323         if(x!=bline_width_)
324         {
325                 bline_width_=x;
326
327                 if(selected_input_device_)
328                         selected_input_device_->set_bline_width(x);
329
330                 signal_bline_width_changed()();
331         }
332 }
333
334 void
335 synfigapp::Main::set_opacity(synfig::Real x)
336 {
337         opacity_=x;
338         if(selected_input_device_)
339                 selected_input_device_->set_opacity(opacity_);
340         signal_opacity_changed()();
341 }
342
343 void
344 synfigapp::Main::set_blend_method(synfig::Color::BlendMethod x)
345 {
346         blend_method_=x;
347         if(selected_input_device_)
348                 selected_input_device_->set_blend_method(x);
349         signal_blend_method_changed()();
350 }
351
352
353 InputDevice::Handle
354 synfigapp::Main::add_input_device(const synfig::String id, InputDevice::Type type)
355 {
356         input_devices_.push_back(new InputDevice(id,type));
357         return input_devices_.back();
358 }
359
360 InputDevice::Handle
361 synfigapp::Main::find_input_device(const synfig::String id)
362 {
363         list<InputDevice::Handle>::iterator iter;
364         for(iter=input_devices_.begin();iter!=input_devices_.end();++iter)
365                 if((*iter)->get_id()==id)
366                         return *iter;
367         return 0;
368 }
369
370 InputDevice::Handle
371 synfigapp::Main::select_input_device(const synfig::String id)
372 {
373         InputDevice::Handle input_device(find_input_device(id));
374         if(!input_device)
375                 return 0;
376         if(!select_input_device(input_device))
377                 return 0;
378         return input_device;
379 }
380
381 bool
382 synfigapp::Main::select_input_device(InputDevice::Handle input_device)
383 {
384         assert(input_device);
385
386         // synfig::info("Input device changed to \"%s\"",input_device->get_id().c_str());
387
388         selected_input_device_=input_device;
389
390         set_bline_width(input_device->get_bline_width());
391         set_foreground_color(input_device->get_foreground_color());
392         set_opacity(input_device->get_opacity());
393         set_blend_method(input_device->get_blend_method());
394
395         return true;
396 }
397
398 InputDevice::Handle
399 synfigapp::Main::get_selected_input_device()
400 {
401         return selected_input_device_;
402 }
403
404 void
405 synfigapp::Main::set_state(synfig::String state)
406 {
407         if(selected_input_device_)
408                 selected_input_device_->set_state(state);
409 }