Allow linking widths and tangents to positions on a bline. It also now works with...
[synfig.git] / synfig-studio / trunk / src / gtkmm / widget_vector.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file widget_vector.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/spinbutton.h>
33 #include "widget_vector.h"
34 #include "widget_distance.h"
35 #include "app.h"
36
37 #include "general.h"
38
39 #endif
40
41 /* === U S I N G =========================================================== */
42
43 using namespace std;
44 using namespace synfig;
45 using namespace studio;
46
47 /* === M A C R O S ========================================================= */
48
49 #define DIGITS          10
50
51 /* === G L O B A L S ======================================================= */
52
53 /* === P R O C E D U R E S ================================================= */
54
55 /* === M E T H O D S ======================================================= */
56
57 Widget_Vector::Widget_Vector():
58         Gtk::HBox(false, 5),
59         x_adjustment(0,-100000000,100000000,0.05,0.05,0.05),
60         y_adjustment(0,-100000000,100000000,0.05,0.05,0.05)
61 {
62         Gtk::Label *label;
63
64         label=manage(new class Gtk::Label("X:"));
65         label->set_alignment(0, 0.5);
66         label->show();
67         pack_start(*label, Gtk::PACK_SHRINK);
68
69         spinbutton_x=manage(new class Gtk::SpinButton(x_adjustment,0.05,DIGITS));
70         spinbutton_x->set_alignment(1);
71         spinbutton_x->set_update_policy(Gtk::UPDATE_ALWAYS);
72         spinbutton_x->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Vector::on_value_changed));
73         pack_start(*spinbutton_x, Gtk::PACK_EXPAND_WIDGET);
74
75         distance_x=manage(new Widget_Distance());
76         distance_x->set_digits(4);
77         distance_x->set_update_policy(Gtk::UPDATE_ALWAYS);
78         distance_x->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Vector::on_value_changed));
79         pack_start(*distance_x, Gtk::PACK_EXPAND_WIDGET);
80
81         label=manage(new class Gtk::Label("Y:"));
82         label->set_alignment(0, 0.5);
83         label->show();
84         pack_start(*label, Gtk::PACK_SHRINK);
85
86         spinbutton_y=manage(new class Gtk::SpinButton(y_adjustment,0.05,DIGITS));
87         spinbutton_y->set_alignment(1);
88         spinbutton_y->set_update_policy(Gtk::UPDATE_ALWAYS);
89         spinbutton_y->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Vector::on_value_changed));
90         spinbutton_y->signal_activate().connect(sigc::mem_fun(*this,&studio::Widget_Vector::activate));
91         pack_start(*spinbutton_y, Gtk::PACK_EXPAND_WIDGET);
92
93         distance_y=manage(new Widget_Distance());
94         distance_y->set_digits(4);
95         distance_y->set_update_policy(Gtk::UPDATE_ALWAYS);
96         distance_y->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Vector::on_value_changed));
97         distance_y->signal_activate().connect(sigc::mem_fun(*this,&studio::Widget_Vector::activate));
98         pack_start(*distance_y, Gtk::PACK_EXPAND_WIDGET);
99
100         spinbutton_x->show();
101         spinbutton_y->show();
102
103         spinbutton_x->signal_activate().connect(sigc::mem_fun(*spinbutton_y,&Gtk::SpinButton::grab_focus));
104         distance_x->signal_activate().connect(sigc::mem_fun(*distance_y,&Gtk::SpinButton::grab_focus));
105 }
106
107 Widget_Vector::~Widget_Vector()
108 {
109 }
110
111 void
112 Widget_Vector::on_grab_focus()
113 {
114         if(canvas_)
115                 distance_x->grab_focus();
116         else
117                 spinbutton_x->grab_focus();
118 }
119
120 void
121 Widget_Vector::set_has_frame(bool x)
122 {
123         if(spinbutton_x)
124         {
125                 spinbutton_x->set_has_frame(x);
126                 spinbutton_y->set_has_frame(x);
127                 spinbutton_x->set_size_request(48,-1);
128                 spinbutton_y->set_size_request(48,-1);
129         }
130
131         distance_x->set_has_frame(x);
132         distance_y->set_has_frame(x);
133         distance_x->set_size_request(48,-1);
134         distance_y->set_size_request(48,-1);
135 }
136
137 void
138 Widget_Vector::set_digits(int x)
139 {
140         if(spinbutton_x)
141         {
142                 spinbutton_x->set_digits(x);
143                 spinbutton_y->set_digits(x);
144                 spinbutton_x->set_size_request(48,-1);
145                 spinbutton_y->set_size_request(48,-1);
146         }
147
148         distance_x->set_digits(x);
149         distance_y->set_digits(x);
150         distance_x->set_size_request(48,-1);
151         distance_y->set_size_request(48,-1);
152 }
153
154 void
155 Widget_Vector::set_value(const synfig::Vector &data)
156 {
157         vector=data;
158
159         if(canvas_){try
160         {
161                 Distance distx(vector[0],Distance::SYSTEM_UNITS),disty(vector[1],Distance::SYSTEM_UNITS);
162                 distx.convert(App::distance_system,canvas_->rend_desc());
163                 disty.convert(App::distance_system,canvas_->rend_desc());
164                 distance_x->set_value(distx);
165                 distance_y->set_value(disty);
166                 spinbutton_x->hide();
167                 spinbutton_y->hide();
168         }catch(...) { synfig::error("Widget_Vector::set_value(): Caught something that was thrown"); }}
169         else
170         {
171                 spinbutton_x->set_value(vector[0]);
172                 spinbutton_y->set_value(vector[1]);
173                 distance_x->hide();
174                 distance_y->hide();
175         }
176 }
177
178 const synfig::Vector &
179 Widget_Vector::get_value()
180 {
181         if(!canvas_ && spinbutton_x)
182         {
183                 vector[0]=spinbutton_x->get_value();
184                 vector[1]=spinbutton_y->get_value();
185                 distance_x->hide();
186                 distance_y->hide();
187         }
188         else try
189         {
190                 vector[0]=distance_x->get_value().units(canvas_->rend_desc());
191                 vector[1]=distance_y->get_value().units(canvas_->rend_desc());
192                 spinbutton_x->hide();
193                 spinbutton_y->hide();
194         }catch(...) { synfig::error("Widget_Vector::set_value(): Caught something that was thrown"); }
195         return vector;
196 }
197
198 void
199 Widget_Vector::on_value_changed()
200 {
201         signal_value_changed()();
202 }
203
204 void
205 Widget_Vector::set_canvas(synfig::Canvas::LooseHandle x)
206 {
207         canvas_=x;
208         if(x)
209         {
210                 if(spinbutton_x)
211                 {
212                         spinbutton_x->hide();
213                         spinbutton_y->hide();
214 //                      delete spinbutton_x;
215 //                      delete spinbutton_y;
216                 }
217                 distance_x->show();
218                 distance_y->show();
219         }
220         else
221         {
222                 if(spinbutton_x)
223                 {
224                         spinbutton_x->show();
225                         spinbutton_y->show();
226                 }
227                 distance_x->hide();
228                 distance_y->hide();
229         }
230 }
231
232 void
233 Widget_Vector::show_all_vfunc()
234 {
235         if(canvas_)
236         {
237                 distance_x->show();
238                 distance_y->show();
239         }
240         else
241         {
242                 spinbutton_x->show();
243                 spinbutton_y->show();
244         }
245         show();
246 }