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