Fix a crash when running single-threaded and dragging the time slider.
[synfig.git] / synfig-studio / trunk / src / gtkmm / widget_value.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file widget_value.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 <gtkmm/label.h>
33 #include "widget_value.h"
34 #include <ETL/stringf>
35 #include <gtkmm/celleditable.h>
36 #include <gtkmm/editable.h>
37 #include <gtkmm/entry.h>
38 #include <gtkmm/eventbox.h>
39 #include <gtk/gtkentry.h> /* see XXX below */
40 #include "app.h"
41
42
43 #include "widget_vector.h"
44 #include "widget_filename.h"
45 #include "widget_enum.h"
46 #include "widget_coloredit.h"
47 #include "widget_canvaschooser.h"
48 #include "widget_time.h"
49 #include "app.h"
50 #include "widget_distance.h"
51
52 #endif
53
54 using namespace synfig;
55 using namespace etl;
56 using namespace std;
57 using namespace studio;
58
59 /* === M A C R O S ========================================================= */
60
61 #define DIGITS          15
62
63 /* === G L O B A L S ======================================================= */
64
65 /* === P R O C E D U R E S ================================================= */
66
67 /* === M E T H O D S ======================================================= */
68
69 Widget_ValueBase::Widget_ValueBase():
70         Glib::ObjectBase        (typeid(Widget_ValueBase)),
71         Gtk::HBox(),
72         real_adjustment(0,-2000000000,2000000000,0.05,0.05,0.05),
73         integer_adjustment(0,-2000000000,2000000000,1,1,1),
74         angle_adjustment(0,-2000000000,2000000000,1,1,1)
75 {
76         set_no_show_all();
77
78         label=manage(new class Gtk::Label("Unknown Datatype"));
79         pack_start(*label);
80         label->show();
81
82         vector_widget=manage(new class Widget_Vector());
83         pack_start(*vector_widget);
84
85         color_widget=manage(new class Widget_ColorEdit());
86         pack_start(*color_widget);
87
88         enum_widget=manage(new class Widget_Enum());
89         pack_start(*enum_widget);
90
91         real_widget=manage(new class Gtk::SpinButton(real_adjustment,0.05,DIGITS));
92         pack_start(*real_widget);
93
94         integer_widget=manage(new class Gtk::SpinButton(integer_adjustment,1,0));
95         pack_start(*integer_widget);
96
97         angle_widget=manage(new class Gtk::SpinButton(angle_adjustment,15,2));
98         pack_start(*angle_widget);
99
100         bool_widget=manage(new class Gtk::CheckButton());
101         pack_start(*bool_widget);
102
103         //color_widget=manage(new class Gtk::ColorSelection());
104         //pack_start(*color_widget);
105
106         string_widget=manage(new class Gtk::Entry());
107         pack_start(*string_widget);
108
109         canvas_widget=manage(new class Widget_CanvasChooser());
110         pack_start(*canvas_widget);
111
112         filename_widget=manage(new class Widget_Filename());
113         pack_start(*filename_widget);
114
115         time_widget=manage(new class Widget_Time());
116         pack_start(*time_widget);
117
118         distance_widget=manage(new class Widget_Distance());
119         pack_start(*distance_widget);
120
121
122         vector_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
123         color_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
124         enum_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
125         real_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
126         integer_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
127         angle_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
128         string_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
129         canvas_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
130         filename_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
131         time_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
132         distance_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
133
134         /*signal_focus_in_event().connect(
135                 sigc::bind_return(
136                 sigc::hide(
137                         sigc::mem_fun(*this,&Widget_ValueBase::grab_focus)
138                 ),false
139                 )
140         );*/
141 }
142
143 Widget_ValueBase::~Widget_ValueBase()
144 {
145 }
146
147 void
148 Widget_ValueBase::activate()
149 {
150         //DEBUGPOINT();
151         signal_activate()();
152 }
153
154 void
155 Widget_ValueBase::inside_cellrenderer()
156 {
157         string_widget->set_has_frame(false);
158         string_widget->gobj()->is_cell_renderer = true; // XXX
159
160         real_widget->set_has_frame(false);
161         //static_cast<Gtk::Entry*>(real_widget)->gobj()->is_cell_renderer = true; // XXX
162
163         distance_widget->set_has_frame(false);
164         //static_cast<Gtk::Entry*>(distance_widget)->gobj()->is_cell_renderer = true; // XXX
165
166         integer_widget->set_has_frame(false);
167         //static_cast<Gtk::Entry*>(integer_widget)->gobj()->is_cell_renderer = true; // XXX
168         vector_widget->set_has_frame(false);
169     //vector_widget->set_digits(10);
170
171         color_widget->set_has_frame(false);
172     //color_widget->set_digits(10);
173         filename_widget->set_has_frame(false);
174         time_widget->set_has_frame(false);
175 }
176
177 void
178 Widget_ValueBase::set_sensitive(bool x)
179 {
180         Gtk::HBox::set_sensitive(x);
181         label->set_sensitive(x);
182         vector_widget->set_sensitive(x);
183         real_widget->set_sensitive(x);
184         integer_widget->set_sensitive(x);
185         bool_widget->set_sensitive(x);
186     color_widget->set_sensitive(x);
187         string_widget->set_sensitive(x);
188         canvas_widget->set_sensitive(x);
189         enum_widget->set_sensitive(x);
190         angle_widget->set_sensitive(x);
191         filename_widget->set_sensitive(x);
192         time_widget->set_sensitive(x);
193         distance_widget->set_sensitive(x);
194 }
195
196 void
197 Widget_ValueBase::set_value(const synfig::ValueBase &data)
198 {
199         label->hide();
200         vector_widget->hide();
201         real_widget->hide();
202         integer_widget->hide();
203         bool_widget->hide();
204     color_widget->hide();
205         string_widget->hide();
206         canvas_widget->hide();
207         enum_widget->hide();
208         angle_widget->hide();
209         filename_widget->hide();
210         time_widget->hide();
211         distance_widget->hide();
212
213         value=data;
214         try{
215         switch(value.get_type())
216         {
217         case ValueBase::TYPE_VECTOR:
218                 vector_widget->set_canvas(canvas);
219                 vector_widget->set_value(value.get(Vector()));
220                 vector_widget->show();
221                 break;
222         case ValueBase::TYPE_REAL:
223                 if(param_desc.get_is_distance() && canvas)
224                 {
225                         Distance dist(value.get(Real()),Distance::SYSTEM_UNITS);
226                         dist.convert(App::distance_system,canvas->rend_desc());
227                         distance_widget->set_value(dist);
228                         distance_widget->show();
229                 }
230                 else
231                 {
232                         real_widget->set_value(value.get(Real()));
233                         real_widget->show();
234                 }
235                 break;
236         case ValueBase::TYPE_TIME:
237                 if(canvas)time_widget->set_fps(canvas->rend_desc().get_frame_rate());
238                 time_widget->set_value(value.get(Time()));
239                 time_widget->show();
240                 break;
241         case ValueBase::TYPE_ANGLE:
242                 angle_widget->set_value(Angle::deg(value.get(Angle())).get());
243                 angle_widget->show();
244                 break;
245         case ValueBase::TYPE_INTEGER:
246                 if(param_desc.get_hint()!="enum")
247                 {
248                         integer_widget->set_value(value.get(int()));
249                         integer_widget->show();
250                 }
251                 else
252                 {
253                         enum_widget->set_param_desc(param_desc);
254                         enum_widget->set_value(value.get(int()));
255                         enum_widget->show();
256                 }
257                 break;
258         case ValueBase::TYPE_CANVAS:
259                 assert(canvas);
260                 canvas_widget->set_parent_canvas(canvas);
261                 canvas_widget->set_value(value.get(etl::loose_handle<synfig::Canvas>()));
262                 canvas_widget->show();
263                 break;
264         case ValueBase::TYPE_BOOL:
265                 bool_widget->set_active(value.get(bool()));
266                 bool_widget->show();
267                 break;
268         case ValueBase::TYPE_STRING:
269                 if(param_desc.get_hint()!="filename")
270                 {
271                         string_widget->set_text(value.get(string()));
272                         string_widget->show();
273                 }
274                 else
275                 {
276                         filename_widget->set_value(value.get(string()));
277                         filename_widget->show();
278                 }
279                 break;
280         case ValueBase::TYPE_COLOR:
281         {
282                 color_widget->set_value(value.get(synfig::Color()));
283                 color_widget->show();
284 /*
285                         Gdk::Color gdkcolor;
286                         synfig::Color color=value.get(synfig::Color());
287                         gdkcolor.set_rgb_p(color.get_r(),color.get_g(),color.get_b());
288                         color_widget->set_current_color(gdkcolor);
289                         color_widget->set_has_opacity_control(true);
290                         color_widget->set_current_alpha((unsigned short)(color.get_a()*65535.0));
291                         color_widget->show();
292 */
293                 }
294                 break;
295         default:
296                 label->show();
297                 break;
298         }
299         }catch(...) { synfig::error(__FILE__":%d: Caught something that was thrown",__LINE__); }
300 }
301
302 const synfig::ValueBase &
303 Widget_ValueBase::get_value()
304 {
305         switch(value.get_type())
306         {
307         case ValueBase::TYPE_VECTOR:
308                 value=vector_widget->get_value();
309                 break;
310         case ValueBase::TYPE_REAL:
311                 if(param_desc.get_is_distance() && canvas)
312                         value=distance_widget->get_value().units(canvas->rend_desc());
313                 else
314                         value=real_widget->get_value();
315                 break;
316         case ValueBase::TYPE_TIME:
317                 value=time_widget->get_value();
318                 break;
319         case ValueBase::TYPE_ANGLE:
320                 value=Angle::deg(angle_widget->get_value());
321                 break;
322         case ValueBase::TYPE_CANVAS:
323                 value=canvas_widget->get_value();
324                 break;
325         case ValueBase::TYPE_INTEGER:
326                 if(param_desc.get_hint()!="enum")
327                 {
328                         value=integer_widget->get_value_as_int();
329                 }
330                 else
331                 {
332                         value=enum_widget->get_value();
333                 }
334
335                 break;
336         case ValueBase::TYPE_BOOL:
337                 value=bool_widget->get_active();
338                 break;
339         case ValueBase::TYPE_STRING:
340                 if(param_desc.get_hint()!="filename")
341                 {
342                         value=string(string_widget->get_text());
343                 }
344                 else
345                 {
346                         value=string(filename_widget->get_value());
347                 }
348                 break;
349         case ValueBase::TYPE_COLOR:
350         {
351                         value=color_widget->get_value();
352 /*
353                         Gdk::Color gdkcolor;
354                         synfig::Color color;
355                         gdkcolor=color_widget->get_current_color();
356                         color.set_r(gdkcolor.get_red_p());
357             color.set_g(gdkcolor.get_green_p());
358             color.set_b(gdkcolor.get_blue_p());
359                         color.set_a(color_widget->get_current_alpha()/65535.0);
360
361                         value=color;
362 */
363                 }
364                 break;
365         default:
366                 break;
367         }
368
369         return value;
370 }
371
372
373 void
374 Widget_ValueBase::on_grab_focus()
375 {
376         switch(value.get_type())
377         {
378         case ValueBase::TYPE_VECTOR:
379                 vector_widget->grab_focus();
380                 break;
381         case ValueBase::TYPE_REAL:
382                 if(param_desc.get_is_distance()&& canvas)
383                         distance_widget->grab_focus();
384                 else
385                         real_widget->grab_focus();
386                 break;
387         case ValueBase::TYPE_TIME:
388                 time_widget->grab_focus();
389                 break;
390         case ValueBase::TYPE_ANGLE:
391                 angle_widget->grab_focus();
392                 break;
393         case ValueBase::TYPE_CANVAS:
394                 canvas_widget->grab_focus();
395                 break;
396         case ValueBase::TYPE_INTEGER:
397                 if(param_desc.get_hint()!="enum")
398                 {
399                         integer_widget->grab_focus();
400                 }
401                 else
402                 {
403                         enum_widget->grab_focus();
404                 }
405
406                 break;
407         case ValueBase::TYPE_BOOL:
408                 bool_widget->grab_focus();
409                 break;
410         case ValueBase::TYPE_STRING:
411                 if(param_desc.get_hint()!="filename")
412                 {
413                         string_widget->grab_focus();
414                 }
415                 else
416                 {
417                         filename_widget->grab_focus();
418                 }
419                 break;
420         case ValueBase::TYPE_COLOR:
421         {
422                         color_widget->grab_focus();
423                 }
424                 break;
425         default:
426                 break;
427         }
428 }
429
430 /*
431 Glib::SignalProxy0<void>
432 Widget_ValueBase::signal_activate()
433 {
434         switch(value.get_type())
435         {
436         case ValueBase::TYPE_VECTOR:
437                 return vector_widget->signal_activate();
438                 break;
439         case ValueBase::TYPE_REAL:
440                 if(param_desc.get_is_distance()&& canvas)
441                         return distance_widget->signal_activate();
442                 else
443                         return real_widget->signal_activate();
444
445                 break;
446         case ValueBase::TYPE_TIME:
447                 return time_widget->signal_activate();
448                 break;
449         case ValueBase::TYPE_ANGLE:
450                 return angle_widget->signal_activate();
451                 break;
452         case ValueBase::TYPE_CANVAS:
453                 return canvas_widget->signal_activate();
454                 break;
455         case ValueBase::TYPE_INTEGER:
456                 if(param_desc.get_hint()!="enum")
457                         return integer_widget->signal_activate();
458                 else
459                         return enum_widget->signal_activate();
460
461                 break;
462         case ValueBase::TYPE_BOOL:
463                 return string_widget->signal_activate();
464                 break;
465         case ValueBase::TYPE_STRING:
466                 if(param_desc.get_hint()!="filename")
467                 {
468                         return string_widget->signal_activate();
469                 }
470                 else
471                 {
472                         return filename_widget->signal_activate();
473                 }
474                 break;
475         case ValueBase::TYPE_COLOR:
476         {
477                         return color_widget->signal_activate();
478                 }
479                 break;
480         default:
481                 return string_widget->signal_activate();
482                 break;
483         }
484 }
485 */