Trying to prevent a crash when changing render quality meanwhile updating work area.
[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 outline_;
61 static Color fill_;
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_outline_color_changed_;
74 trivial<sigc::signal<void> > signal_fill_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         bind_textdomain_codeset("synfigstudio", "UTF-8");
104 #endif
105
106         action_main=new synfigapp::Action::Main();
107
108         settings_.construct();
109
110         signal_outline_color_changed_.construct();
111         signal_fill_color_changed_.construct();
112         signal_gradient_changed_.construct();
113         signal_opacity_changed_.construct();
114         signal_blend_method_changed_.construct();
115         signal_interpolation_changed_.construct();
116
117         set_outline_color(Color::black());
118         set_fill_color(Color::white());
119         set_gradient_default_colors();
120         set_bline_width(Distance(1,Distance::SYSTEM_POINTS));
121         set_opacity(1.0);
122         set_blend_method(Color::BLEND_COMPOSITE);
123 }
124
125 synfigapp::Main::~Main()
126 {
127         ref_count_.detach();
128         if(!synfigapp_ref_count_.unique())
129                 return;
130         synfigapp_ref_count_.detach();
131
132         // Add deinitialization after this point
133
134         delete action_main;
135
136         selected_input_device_=0;
137         input_devices_.clear();
138
139         settings_.destruct();
140         signal_outline_color_changed_.destruct();
141         signal_fill_color_changed_.destruct();
142         signal_gradient_changed_.destruct();
143
144         signal_opacity_changed_.destruct();
145         signal_blend_method_changed_.destruct();
146         signal_interpolation_changed_.destruct();
147 }
148
149 Settings&
150 synfigapp::Main::settings()
151 {
152         return settings_;
153 }
154
155 sigc::signal<void>&
156 synfigapp::Main::signal_outline_color_changed()
157 {
158         return signal_outline_color_changed_;
159 }
160
161 sigc::signal<void>&
162 synfigapp::Main::signal_fill_color_changed()
163 {
164         return signal_fill_color_changed_;
165 }
166
167 sigc::signal<void>&
168 synfigapp::Main::signal_gradient_changed()
169 {
170         return signal_gradient_changed_;
171 }
172
173 sigc::signal<void>&
174 synfigapp::Main::signal_bline_width_changed()
175 {
176         return signal_bline_width_changed_;
177 }
178
179 sigc::signal<void>&
180 synfigapp::Main::signal_blend_method_changed()
181 {
182         return signal_blend_method_changed_;
183 }
184
185 sigc::signal<void>&
186 synfigapp::Main::signal_opacity_changed()
187 {
188         return signal_opacity_changed_;
189 }
190
191 sigc::signal<void>&
192 synfigapp::Main::signal_interpolation_changed()
193 {
194         return signal_interpolation_changed_;
195 }
196
197 const synfig::Color&
198 synfigapp::Main::get_outline_color()
199 {
200         return outline_;
201 }
202
203 const synfig::Color&
204 synfigapp::Main::get_fill_color()
205 {
206         return fill_;
207 }
208
209 const synfig::Gradient&
210 synfigapp::Main::get_gradient()
211 {
212         return gradient_;
213 }
214
215 const synfig::Real&
216 synfigapp::Main::get_opacity()
217 {
218         return opacity_;
219 }
220
221 synfig::Color::BlendMethod
222 synfigapp::Main::get_blend_method()
223 {
224         return blend_method_;
225 }
226
227 void
228 synfigapp::Main::set_outline_color(synfig::Color color)
229 {
230         outline_=color;
231         signal_outline_color_changed()();
232         if(selected_input_device_)
233                 selected_input_device_->set_outline_color(outline_);
234         if(gradient_default_colors_)
235         {
236                 gradient_=Gradient(fill_,outline_);
237                 signal_gradient_changed()();
238         }
239 }
240
241 void
242 synfigapp::Main::set_fill_color(synfig::Color color)
243 {
244         fill_=color;
245         signal_fill_color_changed()();
246
247         if(selected_input_device_)
248                 selected_input_device_->set_fill_color(fill_);
249
250         if(gradient_default_colors_)
251         {
252                 gradient_=Gradient(fill_,outline_);
253                 signal_gradient_changed()();
254         }
255 }
256
257 void
258 synfigapp::Main::set_gradient(synfig::Gradient gradient)
259 {
260         gradient_=gradient;
261         gradient_default_colors_=false;
262         signal_gradient_changed()();
263 }
264
265 void
266 synfigapp::Main::set_gradient_default_colors()
267 {
268         gradient_default_colors_=true;
269         gradient_=Gradient(fill_,outline_);
270         signal_gradient_changed()();
271 }
272
273 void
274 synfigapp::Main::color_swap()
275 {
276         const Color tmp(outline_);
277         outline_=fill_;
278         fill_=tmp;
279
280         if(selected_input_device_)
281         {
282                 selected_input_device_->set_outline_color(outline_);
283                 selected_input_device_->set_fill_color(fill_);
284         }
285
286         signal_outline_color_changed()();
287         signal_fill_color_changed()();
288
289         if(gradient_default_colors_)
290         {
291                 gradient_=Gradient(fill_,outline_);
292                 signal_gradient_changed()();
293         }
294 }
295
296 synfig::Waypoint::Interpolation
297 synfigapp::Main::get_interpolation()
298 {
299         return interpolation_;
300 }
301
302
303 void
304 synfigapp::Main::set_interpolation(synfig::Waypoint::Interpolation x)
305 {
306         if(interpolation_!=x)
307         {
308                 interpolation_=x;
309
310                 signal_interpolation_changed();
311         }
312 }
313
314 const synfig::Distance&
315 synfigapp::Main::get_bline_width()
316 {
317         return bline_width_;
318 }
319
320 void
321 synfigapp::Main::set_bline_width(synfig::Distance x)
322 {
323         if(x<0)x=0;
324         if(x!=bline_width_)
325         {
326                 bline_width_=x;
327
328                 if(selected_input_device_)
329                         selected_input_device_->set_bline_width(x);
330
331                 signal_bline_width_changed()();
332         }
333 }
334
335 void
336 synfigapp::Main::set_opacity(synfig::Real x)
337 {
338         opacity_=x;
339         if(selected_input_device_)
340                 selected_input_device_->set_opacity(opacity_);
341         signal_opacity_changed()();
342 }
343
344 void
345 synfigapp::Main::set_blend_method(synfig::Color::BlendMethod x)
346 {
347         blend_method_=x;
348         if(selected_input_device_)
349                 selected_input_device_->set_blend_method(x);
350         signal_blend_method_changed()();
351 }
352
353
354 InputDevice::Handle
355 synfigapp::Main::add_input_device(const synfig::String id, InputDevice::Type type)
356 {
357         input_devices_.push_back(new InputDevice(id,type));
358         return input_devices_.back();
359 }
360
361 InputDevice::Handle
362 synfigapp::Main::find_input_device(const synfig::String id)
363 {
364         list<InputDevice::Handle>::iterator iter;
365         for(iter=input_devices_.begin();iter!=input_devices_.end();++iter)
366                 if((*iter)->get_id()==id)
367                         return *iter;
368         return 0;
369 }
370
371 InputDevice::Handle
372 synfigapp::Main::select_input_device(const synfig::String id)
373 {
374         InputDevice::Handle input_device(find_input_device(id));
375         if(!input_device)
376                 return 0;
377         if(!select_input_device(input_device))
378                 return 0;
379         return input_device;
380 }
381
382 bool
383 synfigapp::Main::select_input_device(InputDevice::Handle input_device)
384 {
385         assert(input_device);
386
387         // synfig::info("Input device changed to \"%s\"",input_device->get_id().c_str());
388
389         selected_input_device_=input_device;
390
391         set_bline_width(input_device->get_bline_width());
392         set_outline_color(input_device->get_outline_color());
393         set_fill_color(input_device->get_fill_color());
394         set_opacity(input_device->get_opacity());
395         set_blend_method(input_device->get_blend_method());
396
397         return true;
398 }
399
400 InputDevice::Handle
401 synfigapp::Main::get_selected_input_device()
402 {
403         return selected_input_device_;
404 }
405
406 void
407 synfigapp::Main::set_state(synfig::String state)
408 {
409         if(selected_input_device_)
410                 selected_input_device_->set_state(state);
411 }