1 /** \file
2 * Gtkmm facade/wrapper around SPRuler code that formerly lived
3 * in desktop-events.cpp
4 */
5 /*
6 * Authors:
7 * Ralf Stephan <ralf@ark.in-berlin.de>
8 * Lauris Kaplinski
9 * Jon A. Cruz <jon@joncruz.org>
10 * Abhishek Sharma
11 *
12 * Copyright (C) 2005 Ralf Stephan
13 *
14 * Released under GNU GPL, read the file 'COPYING' for more information
15 */
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
21 #include <glibmm/i18n.h>
23 #include <gtkmm/ruler.h>
24 #include "helper/units.h"
25 #include "widgets/ruler.h"
26 #include "ui/widget/ruler.h"
28 #include "xml/repr.h"
29 #include "display/sp-canvas.h"
30 #include "display/guideline.h"
31 #include "desktop.h"
32 #include "desktop-handles.h"
33 #include "document.h"
34 #include "sp-namedview.h"
35 #include "verbs.h"
37 namespace Inkscape {
38 namespace UI {
39 namespace Widget {
41 void
42 Ruler::init(SPDesktop *dt, Gtk::Widget &w)
43 {
44 _dt = dt;
45 _canvas_widget = &w;
46 _dragging = false;
47 _guide = 0;
48 sp_ruler_set_metric(GTK_RULER(_r->gobj()), SP_PT);
49 _r->set_range(-500, 500, 0, 1000);
50 }
52 void
53 Ruler::get_range(double &lo, double &up, double &pos, double &max)
54 {
55 _r->get_range(lo, up, pos, max);
56 }
58 void
59 Ruler::set_range(double lo, double up, double pos, double max)
60 {
61 _r->set_range(lo, up, pos, max);
62 }
64 /// Set metric from namedview
65 void
66 Ruler::update_metric()
67 {
68 if (!_dt) return;
69 sp_ruler_set_metric(GTK_RULER(_r->gobj()), _dt->namedview->getDefaultMetric());
70 }
72 /// Returns text to be used for tooltip for ruler.
73 /// \todo incorrect
74 Glib::ustring
75 Ruler::get_tip()
76 {
77 return gettext(sp_unit_get_plural( _dt
78 ? _dt->namedview->doc_units
79 : &sp_unit_get_by_id(SP_UNIT_PT) ));
80 }
82 /// Helper that gets mouse coordinates relative to canvas widget.
83 void
84 Ruler::canvas_get_pointer(int &x, int &y)
85 {
86 Gdk::ModifierType mask;
87 (void) _canvas_widget->get_window()->get_pointer(x, y, mask);
88 }
90 Geom::Point
91 Ruler::get_event_dt()
92 {
93 int wx, wy;
94 canvas_get_pointer(wx, wy);
95 Geom::Point const event_win(wx, wy);
96 Geom::Point const event_w(sp_canvas_window_to_world(_dt->canvas, event_win));
97 return _dt->w2d(event_w);
98 }
100 bool
101 Ruler::on_button_press_event(GdkEventButton *evb)
102 {
103 g_assert(_dt);
104 Geom::Point const &event_dt = get_event_dt();
105 Inkscape::XML::Node *repr = SP_OBJECT_REPR(_dt->namedview);
107 if (evb->button == 1) {
108 _dragging = true;
109 sp_repr_set_boolean(repr, "showguides", TRUE);
110 sp_repr_set_boolean(repr, "inkscape:guide-bbox", TRUE);
111 _guide = sp_guideline_new(_dt->guides, event_dt, _horiz_f ? Geom::Point(0.,1.) : Geom::Point(1.,0.));
112 sp_guideline_set_color(SP_GUIDELINE(_guide), _dt->namedview->guidehicolor);
113 (void) get_window()->pointer_grab(false,
114 Gdk::BUTTON_RELEASE_MASK |
115 Gdk::POINTER_MOTION_MASK |
116 Gdk::POINTER_MOTION_HINT_MASK,
117 evb->time);
118 }
119 return false;
120 }
122 bool
123 Ruler::on_motion_notify_event(GdkEventMotion *)
124 {
125 g_assert(_dt);
126 Geom::Point const &event_dt = get_event_dt();
128 if (_dragging) {
129 sp_guideline_set_position(SP_GUIDELINE(_guide), event_dt);
130 _dt->set_coordinate_status(event_dt);
131 _dt->setPosition(event_dt);
132 }
133 return false;
134 }
136 bool
137 Ruler::on_button_release_event(GdkEventButton *evb)
138 {
139 g_assert(_dt);
140 int wx, wy;
141 canvas_get_pointer(wx, wy);
142 Geom::Point const &event_dt = get_event_dt();
144 if (_dragging && evb->button == 1) {
145 Gdk::Window::pointer_ungrab(evb->time);
146 gtk_object_destroy(GTK_OBJECT(_guide));
147 _guide = 0;
148 _dragging = false;
150 if ( (_horiz_f ? wy : wx ) >= 0 ) {
151 Inkscape::XML::Document *xml_doc = _dt->doc()->getReprDoc();
152 Inkscape::XML::Node *repr = xml_doc->createElement("sodipodi:guide");
153 repr->setAttribute("orientation", _horiz_f ? "horizontal" : "vertical");
154 double const guide_pos_dt = event_dt[ _horiz_f ? Geom::Y : Geom::X ];
155 sp_repr_set_svg_double(repr, "position", guide_pos_dt);
156 SP_OBJECT_REPR(_dt->namedview)->appendChild(repr);
157 Inkscape::GC::release(repr);
158 DocumentUndo::done(sp_desktop_document(_dt), SP_VERB_NONE,
159 /* TODO: annotate */ "ruler.cpp:157");
160 }
161 _dt->set_coordinate_status(event_dt);
162 }
163 return false;
164 }
166 //------------------------------------------------------------
167 HRuler::HRuler()
168 {
169 _dt = 0;
170 _r = static_cast<Gtk::HRuler*>(Glib::wrap(static_cast<GtkWidget*> (sp_hruler_new())));
171 add(*_r);
172 _horiz_f = true;
173 }
175 HRuler::~HRuler()
176 {
177 }
180 VRuler::VRuler()
181 {
182 _dt = 0;
183 _r = static_cast<Gtk::VRuler*>(Glib::wrap(static_cast<GtkWidget*> (sp_vruler_new())));
184 add(*_r);
185 _horiz_f = false;
186 }
188 VRuler::~VRuler()
189 {
190 }
192 }}}
194 /*
195 Local Variables:
196 mode:c++
197 c-file-style:"stroustrup"
198 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
199 indent-tabs-mode:nil
200 fill-column:99
201 End:
202 */
203 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :