Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / ui / dialog / guides.cpp
1 /** @file
2  * @brief Simple guideline dialog
3  */
4 /* Authors:
5  *   Lauris Kaplinski <lauris@kaplinski.com>
6  *   Andrius R. <knutux@gmail.com>
7  *   Johan Engelen
8  *   Abhishek Sharma
9  *
10  * Copyright (C) 1999-2007 Authors
11  *
12  * Released under GNU GPL, read the file 'COPYING' for more information
13  */
15 #ifdef HAVE_CONFIG_H
16 # include <config.h>
17 #endif
18 #include "display/guideline.h"
19 #include "helper/unit-menu.h"
20 #include "helper/units.h"
21 #include "desktop.h"
22 #include "document.h"
23 #include "sp-guide.h"
24 #include "sp-namedview.h"
25 #include "desktop-handles.h"
26 #include "event-context.h"
27 #include "widgets/desktop-widget.h"
28 #include "sp-metrics.h"
29 #include <glibmm/i18n.h>
30 #include "dialogs/dialog-events.h"
31 #include "message-context.h"
32 #include "xml/repr.h"
33 #include <2geom/point.h>
34 #include <2geom/angle.h>
35 #include "guides.h"
37 namespace Inkscape {
38 namespace UI {
39 namespace Dialogs {
41 GuidelinePropertiesDialog::GuidelinePropertiesDialog(SPGuide *guide, SPDesktop *desktop)
42 : _desktop(desktop), _guide(guide),
43   _label_units(_("Unit:")),
44   _label_X(_("X:")),
45   _label_Y(_("Y:")),
46   _label_degrees(_("Angle (degrees):")),
47   _relative_toggle(_("Rela_tive change"), _("Move and/or rotate the guide relative to current settings")),
48   _adjustment_x(0.0, -1e6, 1e6, 1.0, 10.0, 10.0),  
49   _adjustment_y(0.0, -1e6, 1e6, 1.0, 10.0, 10.0),  
50   _adj_angle(0.0, -360, 360, 1.0, 10.0, 10.0),  
51   _unit_selector(NULL), _mode(true), _oldpos(0.,0.), _oldangle(0.0)
52 {
53 }
55 GuidelinePropertiesDialog::~GuidelinePropertiesDialog() {
56 }
58 void GuidelinePropertiesDialog::showDialog(SPGuide *guide, SPDesktop *desktop) {
59     GuidelinePropertiesDialog dialog(guide, desktop);
60     dialog._setup();
61     dialog.run();
62 }
64 void GuidelinePropertiesDialog::_modeChanged()
65 {
66     _mode = !_relative_toggle.get_active();
67     if (!_mode) {
68         // relative
69         _spin_angle.set_value(0);
71         _spin_button_y.set_value(0);
72         _spin_button_x.set_value(0);
73     } else {
74         // absolute
75         _spin_angle.set_value(_oldangle);
77         SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_unit_selector->gobj()));
78         gdouble const val_y = sp_pixels_get_units(_oldpos[Geom::Y], unit);
79         _spin_button_y.set_value(val_y);
80         gdouble const val_x = sp_pixels_get_units(_oldpos[Geom::X], unit);
81         _spin_button_x.set_value(val_x);
82     }
83 }
85 void GuidelinePropertiesDialog::_onApply()
86 {
87     double deg_angle = _spin_angle.get_value();
88     if (!_mode)
89         deg_angle += _oldangle;
90     Geom::Point normal;
91     if ( deg_angle == 90. || deg_angle == 270. || deg_angle == -90. || deg_angle == -270.) {
92         normal = Geom::Point(1.,0.);
93     } else if ( deg_angle == 0. || deg_angle == 180. || deg_angle == -180.) {
94         normal = Geom::Point(0.,1.);
95     } else {
96         double rad_angle = Geom::deg_to_rad( deg_angle );
97         normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0));
98     }
99     sp_guide_set_normal(*_guide, normal, true);
101     SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_unit_selector->gobj()));
102     gdouble const raw_dist_x = _spin_button_x.get_value();
103     gdouble const points_x = sp_units_get_pixels(raw_dist_x, unit);
104     gdouble const raw_dist_y = _spin_button_y.get_value();
105     gdouble const points_y = sp_units_get_pixels(raw_dist_y, unit);
106     Geom::Point newpos(points_x, points_y);
107     if (!_mode)
108         newpos += _oldpos;
110     sp_guide_moveto(*_guide, newpos, true);
112     DocumentUndo::done(SP_OBJECT_DOCUMENT(_guide), SP_VERB_NONE, 
113                        _("Set guide properties"));
116 void GuidelinePropertiesDialog::_onOK()
118     _onApply();
121 void GuidelinePropertiesDialog::_onDelete()
123     SPDocument *doc = SP_OBJECT_DOCUMENT(_guide);
124     sp_guide_remove(_guide);
125     DocumentUndo::done(doc, SP_VERB_NONE, 
126                        _("Delete guide"));
129 void GuidelinePropertiesDialog::_response(gint response)
131     switch (response) {
132         case Gtk::RESPONSE_OK:
133             _onOK();
134             break;
135         case -12:
136             _onDelete();
137             break;
138         case Gtk::RESPONSE_CANCEL:
139             break;
140         case Gtk::RESPONSE_DELETE_EVENT:
141             break;
142 /*      case GTK_RESPONSE_APPLY:
143         _onApply();
144         break;
145 */
146         default:
147             g_assert_not_reached();
148     }
151 void GuidelinePropertiesDialog::_setup() {
152     set_title(_("Guideline"));
153     add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
154     add_button(Gtk::Stock::DELETE, -12);
155     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
157     Gtk::VBox *mainVBox = get_vbox();
159     _layout_table.set_spacings(4);
160     _layout_table.resize (3, 4);
162     mainVBox->pack_start(_layout_table, false, false, 0);
164     _label_name.set_label("foo0");
165     _layout_table.attach(_label_name,
166                          0, 3, 0, 1, Gtk::FILL, Gtk::FILL);
167     _label_name.set_alignment(0, 0.5);
169     _label_descr.set_label("foo1");
170     _layout_table.attach(_label_descr,
171                          0, 3, 1, 2, Gtk::FILL, Gtk::FILL);
172     _label_descr.set_alignment(0, 0.5);
174     // indent
175     _layout_table.attach(*manage(new Gtk::Label(" ")),
176                          0, 1, 2, 3, Gtk::FILL, Gtk::FILL, 10);
178     // mode radio button
179     _layout_table.attach(_relative_toggle,
180                          1, 3, 9, 10, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
181     _relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged));
183     // unitmenu
184     /* fixme: We should allow percents here too, as percents of the canvas size */
185     GtkWidget *unit_selector = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
186     sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unit_selector), _desktop->namedview->doc_units);
187     _unit_selector = Gtk::manage(Glib::wrap(unit_selector));
189     // position spinbuttons
190     sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(unit_selector), GTK_ADJUSTMENT(_adjustment_x.gobj()));
191     sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(unit_selector), GTK_ADJUSTMENT(_adjustment_y.gobj()));
192     _spin_button_x.configure(_adjustment_x, 1.0 , 3);
193     _spin_button_x.set_numeric();
194     _spin_button_y.configure(_adjustment_y, 1.0 , 3);
195     _spin_button_y.set_numeric();
196     _layout_table.attach(_label_X,
197                          1, 2, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
198     _layout_table.attach(_spin_button_x,
199                          2, 3, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
200     _layout_table.attach(_label_Y,
201                          1, 2, 5, 6, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
202     _layout_table.attach(_spin_button_y,
203                          2, 3, 5, 6, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
204     gtk_signal_connect_object(GTK_OBJECT(_spin_button_x.gobj()), "activate",
205                               GTK_SIGNAL_FUNC(gtk_window_activate_default),
206                               gobj());
208     _layout_table.attach(_label_units,
209                          1, 2, 6, 7, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
210     _layout_table.attach(*_unit_selector,
211                          2, 3, 6, 7, Gtk::FILL, Gtk::FILL);
213     // angle spinbutton
214     _spin_angle.configure(_adj_angle, 5.0 , 3);
215     _spin_angle.set_numeric();
216     _spin_angle.show();
217     _layout_table.attach(_label_degrees,
218                          1, 2, 8, 9, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
219     _layout_table.attach(_spin_angle,
220                          2, 3, 8, 9, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
223     // dialog
224     set_default_response(Gtk::RESPONSE_OK);
225     signal_response().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_response));
227     // initialize dialog
228     _oldpos = _guide->point_on_line;
229     if (_guide->isVertical()) {
230         _oldangle = 90;
231     } else if (_guide->isHorizontal()) {
232         _oldangle = 0;
233     } else {
234         _oldangle = Geom::rad_to_deg( std::atan2( - _guide->normal_to_line[Geom::X], _guide->normal_to_line[Geom::Y] ) );
235     }
237     {
238         Inkscape::XML::Node *repr = SP_OBJECT_REPR (_guide);
239         const gchar *guide_id = repr->attribute("id");
240         gchar *label = g_strdup_printf(_("Guideline ID: %s"), guide_id);
241         _label_name.set_label(label);
242         g_free(label);
243     }
244     {
245         gchar *guide_description = sp_guide_description(_guide, false);
246         gchar *label = g_strdup_printf(_("Current: %s"), guide_description);
247         g_free(guide_description);
248         _label_descr.set_markup(label);
249         g_free(label);
250     }
252     _modeChanged(); // sets values of spinboxes.
254     if ( _oldangle == 90. || _oldangle == 270. || _oldangle == -90. || _oldangle == -270.) {
255         _spin_button_x.grab_focus();
256         _spin_button_x.select_region(0, 20);
257     } else if ( _oldangle == 0. || _oldangle == 180. || _oldangle == -180.) {
258         _spin_button_y.grab_focus();
259         _spin_button_y.select_region(0, 20);
260     } else {
261         _spin_angle.grab_focus();
262         _spin_angle.select_region(0, 20);
263     }
265     set_position(Gtk::WIN_POS_MOUSE);
267     show_all_children();
268     set_modal(true);
269     _desktop->setWindowTransient (gobj());
270     property_destroy_with_parent() = true;
277 /*
278   Local Variables:
279   mode:c++
280   c-file-style:"stroustrup"
281   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
282   indent-tabs-mode:nil
283   fill-column:99
284   End:
285 */
286 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :