Code

fix cursor placement logic
[inkscape.git] / src / dialogs / guidelinedialog.cpp
index 6f8639d4c1c5c48098ad3328786acb65c1e44301..f0115ee913cd6dae305a329fd1c0dda49c8ea6fd 100644 (file)
@@ -1,13 +1,12 @@
-#define __GUIDELINE_CPP__
-
-/*
- * simple guideline dialog
- *
- * Authors:
+/** @file
+ * @brief Simple guideline dialog
+ */
+/* Authors:
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   Andrius R. <knutux@gmail.com>
+ *   Johan Engelen
  *
- * Copyright (C) 1999-2006 Authors
+ * Copyright (C) 1999-2007 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -30,7 +29,8 @@
 #include "dialogs/dialog-events.h"
 #include "message-context.h"
 #include "xml/repr.h"
-
+#include <2geom/point.h>
+#include <2geom/angle.h>
 #include "guidelinedialog.h"
 
 namespace Inkscape {
@@ -39,49 +39,77 @@ namespace Dialogs {
 
 GuidelinePropertiesDialog::GuidelinePropertiesDialog(SPGuide *guide, SPDesktop *desktop)
 : _desktop(desktop), _guide(guide),
-  _a(0.0, -SP_DESKTOP_SCROLL_LIMIT, SP_DESKTOP_SCROLL_LIMIT, 1.0, 10.0, 10.0),
-  _u(NULL), _mode(true), _oldpos(0.0)
+  _label_units(_("Unit:")),
+  _label_X(_("X:")),
+  _label_Y(_("Y:")),
+  _label_degrees(_("Angle (degrees):")),
+  _relative_toggle(_("Rela_tive change"), _("Move and/or rotate the guide relative to current settings")),
+  _adjustment_x(0.0, -1e6, 1e6, 1.0, 10.0, 10.0),  
+  _adjustment_y(0.0, -1e6, 1e6, 1.0, 10.0, 10.0),  
+  _adj_angle(0.0, -360, 360, 1.0, 10.0, 10.0),  
+  _unit_selector(NULL), _mode(true), _oldpos(0.,0.), _oldangle(0.0)
 {
 }
 
 GuidelinePropertiesDialog::~GuidelinePropertiesDialog() {
-    if ( NULL != _u) {
-        //g_free(_u);
-    }
 }
 
 void GuidelinePropertiesDialog::showDialog(SPGuide *guide, SPDesktop *desktop) {
-    GuidelinePropertiesDialog *dialog = new GuidelinePropertiesDialog(guide, desktop);
-    dialog->_setup();
-    dialog->run();
-    delete dialog;
+    GuidelinePropertiesDialog dialog(guide, desktop);
+    dialog._setup();
+    dialog.run();
 }
 
 void GuidelinePropertiesDialog::_modeChanged()
 {
-    if (_mode) {
-        // TRANSLATORS: This string appears when double-clicking on a guide.
-        // This is the distance by which the guide is to be moved.
-        _m.set_label(_(" relative by "));
-        _mode = false;
+    _mode = !_relative_toggle.get_active();
+    if (!_mode) {
+        // relative
+        _spin_angle.set_value(0);
+
+        _spin_button_y.set_value(0);
+        _spin_button_x.set_value(0);
     } else {
-        // TRANSLATORS: This string appears when double-clicking on a guide.
-        // This is the target location where the guide is to be moved.
-        _m.set_label(_(" absolute to "));
-        _mode = true;
+        // absolute
+        _spin_angle.set_value(_oldangle);
+
+        SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_unit_selector->gobj()));
+        gdouble const val_y = sp_pixels_get_units(_oldpos[Geom::Y], unit);
+        _spin_button_y.set_value(val_y);
+        gdouble const val_x = sp_pixels_get_units(_oldpos[Geom::X], unit);
+        _spin_button_x.set_value(val_x);
     }
 }
 
 void GuidelinePropertiesDialog::_onApply()
 {
-    gdouble const raw_dist = _e.get_value();
-    SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_u));
-    gdouble const points = sp_units_get_pixels(raw_dist, unit);
-    gdouble const newpos = ( _mode
-                             ? points
-                             : _guide->position + points );
+    double deg_angle = _spin_angle.get_value();
+    if (!_mode)
+        deg_angle += _oldangle;
+    Geom::Point normal;
+    if ( deg_angle == 90. || deg_angle == 270. || deg_angle == -90. || deg_angle == -270.) {
+        normal = Geom::Point(1.,0.);
+    } else if ( deg_angle == 0. || deg_angle == 180. || deg_angle == -180.) {
+        normal = Geom::Point(0.,1.);
+    } else {
+        double rad_angle = Geom::deg_to_rad( deg_angle );
+        normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0));
+    }
+    sp_guide_set_normal(*_guide, normal, true);
+
+    SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_unit_selector->gobj()));
+    gdouble const raw_dist_x = _spin_button_x.get_value();
+    gdouble const points_x = sp_units_get_pixels(raw_dist_x, unit);
+    gdouble const raw_dist_y = _spin_button_y.get_value();
+    gdouble const points_y = sp_units_get_pixels(raw_dist_y, unit);
+    Geom::Point newpos(points_x, points_y);
+    if (!_mode)
+        newpos += _oldpos;
+
     sp_guide_moveto(*_guide, newpos, true);
-    sp_document_done(SP_OBJECT_DOCUMENT(_guide));
+
+    sp_document_done(SP_OBJECT_DOCUMENT(_guide), SP_VERB_NONE, 
+                     _("Set guide properties"));
 }
 
 void GuidelinePropertiesDialog::_onOK()
@@ -93,7 +121,8 @@ void GuidelinePropertiesDialog::_onDelete()
 {
     SPDocument *doc = SP_OBJECT_DOCUMENT(_guide);
     sp_guide_remove(_guide);
-    sp_document_done(doc);
+    sp_document_done(doc, SP_VERB_NONE, 
+                     _("Delete guide"));
 }
 
 void GuidelinePropertiesDialog::_response(gint response)
@@ -105,7 +134,7 @@ void GuidelinePropertiesDialog::_response(gint response)
        case -12:
             _onDelete();
             break;
-       case Gtk::RESPONSE_CLOSE:
+       case Gtk::RESPONSE_CANCEL:
             break;
        case Gtk::RESPONSE_DELETE_EVENT:
             break;
@@ -122,58 +151,72 @@ void GuidelinePropertiesDialog::_setup() {
     set_title(_("Guideline"));
     add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
     add_button(Gtk::Stock::DELETE, -12);
-    add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
+    add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
 
     Gtk::VBox *mainVBox = get_vbox();
 
-    _b1.set_homogeneous(false);
-    _b1.set_spacing(4);
-    mainVBox->pack_start(_b1, false, false, 0);
-    _b1.set_border_width(4);
-
-    _b2.set_homogeneous(false);
-    _b2.set_spacing(4);
-    _b1.pack_start(_b2, true, true, 0);
+    _layout_table.set_spacings(4);
+    _layout_table.resize (3, 4);
 
-    //labels
-    _b3.set_homogeneous(false);
-    _b3.set_spacing(4);
-    _b2.pack_start(_b3, true, true, 0);
+    mainVBox->pack_start(_layout_table, false, false, 0);
 
-    _l1.set_label("foo1");
-    _b3.pack_start(_l1, true, true, 0);
-    _l1.set_alignment(1.0, 0.5);
+    _label_name.set_label("foo0");
+    _layout_table.attach(_label_name,
+                         0, 3, 0, 1, Gtk::FILL, Gtk::FILL);
+    _label_name.set_alignment(0, 0.5);
 
-    _l2.set_label("foo2");
-    _b3.pack_start(_l2, true, true, 0);
-    _l2.set_alignment(0.0, 0.5);
+    _label_descr.set_label("foo1");
+    _layout_table.attach(_label_descr,
+                         0, 3, 1, 2, Gtk::FILL, Gtk::FILL);
+    _label_descr.set_alignment(0, 0.5);
 
-    _b4.set_homogeneous(false);
-    _b4.set_spacing(4);
-    _b2.pack_start(_b4, false, false, 0);
+    // indent
+    _layout_table.attach(*manage(new Gtk::Label(" ")),
+                         0, 1, 2, 3, Gtk::FILL, Gtk::FILL, 10);
 
-    // mode button
-    _but.set_relief(Gtk::RELIEF_NONE);
-    _b4.pack_start(_but, false, true, 0);
-    _but.signal_clicked().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged));
-    _m.set_label(_(" absolute to "));
-    _but.add(_m);
+    // mode radio button
+    _layout_table.attach(_relative_toggle,
+                         1, 3, 9, 10, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged));
 
     // unitmenu
     /* fixme: We should allow percents here too, as percents of the canvas size */
-    _u = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
-    sp_unit_selector_set_unit(SP_UNIT_SELECTOR(_u), _desktop->namedview->doc_units);
-
-    // spinbutton
-    sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(_u), GTK_ADJUSTMENT(_a.gobj()));
-    _e.configure(_a, 1.0 , 2);
-    _e.set_numeric(TRUE);
-    _b4.pack_start(_e, true, true, 0);
-    gtk_signal_connect_object(GTK_OBJECT(_e.gobj()), "activate",
+    GtkWidget *unit_selector = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
+    sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unit_selector), _desktop->namedview->doc_units);
+    _unit_selector = Gtk::manage(Glib::wrap(unit_selector));
+
+    // position spinbuttons
+    sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(unit_selector), GTK_ADJUSTMENT(_adjustment_x.gobj()));
+    sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(unit_selector), GTK_ADJUSTMENT(_adjustment_y.gobj()));
+    _spin_button_x.configure(_adjustment_x, 1.0 , 3);
+    _spin_button_x.set_numeric();
+    _spin_button_y.configure(_adjustment_y, 1.0 , 3);
+    _spin_button_y.set_numeric();
+    _layout_table.attach(_label_X,
+                         1, 2, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_spin_button_x,
+                         2, 3, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_label_Y,
+                         1, 2, 5, 6, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_spin_button_y,
+                         2, 3, 5, 6, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    gtk_signal_connect_object(GTK_OBJECT(_spin_button_x.gobj()), "activate",
                               GTK_SIGNAL_FUNC(gtk_window_activate_default),
                               gobj());
 
-    gtk_box_pack_start(GTK_BOX(_b4.gobj()), _u, FALSE, FALSE, 0);
+    _layout_table.attach(_label_units,
+                         1, 2, 6, 7, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(*_unit_selector,
+                         2, 3, 6, 7, Gtk::FILL, Gtk::FILL);
+
+    // angle spinbutton
+    _spin_angle.configure(_adj_angle, 5.0 , 3);
+    _spin_angle.set_numeric();
+    _spin_angle.show();
+    _layout_table.attach(_label_degrees,
+                         1, 2, 8, 9, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_spin_angle,
+                         2, 3, 8, 9, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
 
 
     // dialog
@@ -181,20 +224,43 @@ void GuidelinePropertiesDialog::_setup() {
     signal_response().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_response));
 
     // initialize dialog
-    _oldpos = _guide->position;
+    _oldpos = _guide->point_on_line;
+    if (_guide->is_vertical()) {
+        _oldangle = 90;
+    } else if (_guide->is_horizontal()) {
+        _oldangle = 0;
+    } else {
+        _oldangle = Geom::rad_to_deg( std::atan2( - _guide->normal_to_line[Geom::X], _guide->normal_to_line[Geom::Y] ) );
+    }
+
+    {
+        Inkscape::XML::Node *repr = SP_OBJECT_REPR (_guide);
+        const gchar *guide_id = repr->attribute("id");
+        gchar *label = g_strdup_printf(_("Guideline ID: %s"), guide_id);
+        _label_name.set_label(label);
+        g_free(label);
+    }
     {
         gchar *guide_description = sp_guide_description(_guide);
-        gchar *label = g_strdup_printf(_("Move %s"), guide_description);
+        gchar *label = g_strdup_printf(_("Current: %s"), guide_description);
         g_free(guide_description);
-        _l1.set_label(label);
+        _label_descr.set_markup(label);
         g_free(label);
     }
 
-    SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_u));
-    gdouble const val = sp_pixels_get_units(_oldpos, unit);
-    _e.set_value(val);
-    _e.grab_focus();
-    _e.select_region(0, 20);
+    _modeChanged(); // sets values of spinboxes.
+
+    if ( _oldangle == 90. || _oldangle == 270. || _oldangle == -90. || _oldangle == -270.) {
+        _spin_button_x.grab_focus();
+        _spin_button_x.select_region(0, 20);
+    } else if ( _oldangle == 0. || _oldangle == 180. || _oldangle == -180.) {
+        _spin_button_y.grab_focus();
+        _spin_button_y.select_region(0, 20);
+    } else {
+        _spin_angle.grab_focus();
+        _spin_angle.select_region(0, 20);
+    }
+
     set_position(Gtk::WIN_POS_MOUSE);
 
     show_all_children();
@@ -217,4 +283,3 @@ void GuidelinePropertiesDialog::_setup() {
   End:
 */
 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
-