1 /**
2 \file grid.cpp
4 A plug-in to add a grid creation effect into Inkscape.
5 */
6 /*
7 * Authors:
8 * Ted Gould <ted@gould.cx>
9 *
10 * Copyright (C) 2004-2005 Authors
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
15 #include <gtkmm/box.h>
16 #include <gtkmm/adjustment.h>
17 #include <gtkmm/spinbutton.h>
19 #include "desktop.h"
20 #include "selection.h"
21 #include "sp-object.h"
23 #include "extension/effect.h"
24 #include "extension/system.h"
27 #include "grid.h"
29 namespace Inkscape {
30 namespace Extension {
31 namespace Internal {
33 /**
34 \brief A function to allocated anything -- just an example here
35 \param module Unused
36 \return Whether the load was sucessful
37 */
38 bool
39 Grid::load (Inkscape::Extension::Extension *module)
40 {
41 // std::cout << "Hey, I'm Grid, I'm loading!" << std::endl;
42 return TRUE;
43 }
45 /**
46 \brief This actually draws the grid.
47 \param module The effect that was called (unused)
48 \param document What should be edited.
49 */
50 void
51 Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document)
52 {
53 Inkscape::Selection * selection = ((SPDesktop *)document)->selection;
55 NR::Rect bounding_area = NR::Rect(NR::Point(0,0), NR::Point(100,100));
56 if (selection->isEmpty()) {
57 /* get page size */
58 SPDocument * doc = document->doc();
59 bounding_area = NR::Rect(NR::Point(0,0),
60 NR::Point(sp_document_width(doc),
61 sp_document_height(doc)));
62 } else {
63 bounding_area = selection->bounds();
65 gdouble doc_height = sp_document_height(document->doc());
66 NR::Rect temprec = NR::Rect(NR::Point(bounding_area.min()[NR::X], doc_height - bounding_area.min()[NR::Y]),
67 NR::Point(bounding_area.max()[NR::X], doc_height - bounding_area.max()[NR::Y]));
69 bounding_area = temprec;
70 }
73 float xspacing = module->get_param_float("xspacing");
74 float yspacing = module->get_param_float("yspacing");
75 float line_width = module->get_param_float("lineWidth");
76 float xoffset = module->get_param_float("xoffset");
77 float yoffset = module->get_param_float("yoffset");
79 // std::cout << "Spacing: " << spacing;
80 // std::cout << " Line Width: " << line_width;
81 // std::cout << " Offset: " << offset << std::endl;
83 Glib::ustring path_data;
85 for (NR::Point start_point = bounding_area.min();
86 start_point[NR::X] + xoffset <= (bounding_area.max())[NR::X];
87 start_point[NR::X] += xspacing) {
88 NR::Point end_point = start_point;
89 end_point[NR::Y] = (bounding_area.max())[NR::Y];
90 gchar floatstring[64];
92 path_data += "M ";
93 sprintf(floatstring, "%f", start_point[NR::X] + xoffset);
94 path_data += floatstring;
95 path_data += " ";
96 sprintf(floatstring, "%f", start_point[NR::Y]);
97 path_data += floatstring;
98 path_data += " L ";
99 sprintf(floatstring, "%f", end_point[NR::X] + xoffset);
100 path_data += floatstring;
101 path_data += " ";
102 sprintf(floatstring, "%f", end_point[NR::Y]);
103 path_data += floatstring;
104 path_data += " ";
105 }
107 for (NR::Point start_point = bounding_area.min();
108 start_point[NR::Y] + yoffset <= (bounding_area.max())[NR::Y];
109 start_point[NR::Y] += yspacing) {
110 NR::Point end_point = start_point;
111 end_point[NR::X] = (bounding_area.max())[NR::X];
112 gchar floatstring[64];
114 path_data += "M ";
115 sprintf(floatstring, "%f", start_point[NR::X]);
116 path_data += floatstring;
117 path_data += " ";
118 sprintf(floatstring, "%f", start_point[NR::Y] + yoffset);
119 path_data += floatstring;
120 path_data += " L ";
121 sprintf(floatstring, "%f", end_point[NR::X]);
122 path_data += floatstring;
123 path_data += " ";
124 sprintf(floatstring, "%f", end_point[NR::Y] + yoffset);
125 path_data += floatstring;
126 path_data += " ";
127 }
129 // std::cout << "Path Data: " << path_data << std::endl;
131 Inkscape::XML::Node * current_layer = ((SPDesktop *)document)->currentLayer()->repr;
132 Inkscape::XML::Node * path = sp_repr_new("svg:path");
134 path->setAttribute("d", path_data.c_str());
136 Glib::ustring style("fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000");
137 style += ";stroke-width:";
138 gchar floatstring[64];
139 sprintf(floatstring, "%f", line_width);
140 style += floatstring;
141 style += "pt";
142 path->setAttribute("style", style.c_str());
144 // Glib::ustring transform("scale(1.25 1.25)");
145 // path->setAttribute("transform", transform.c_str());
147 current_layer->appendChild(path);
149 return;
150 }
152 /** \brief A class to make an adjustment that uses Extension params */
153 class PrefAdjustment : public Gtk::Adjustment {
154 /** Extension that this relates to */
155 Inkscape::Extension::Extension * _ext;
156 /** The string which represents the parameter */
157 char * _pref;
158 public:
159 /** \brief Make the adjustment using an extension and the string
160 describing the parameter. */
161 PrefAdjustment(Inkscape::Extension::Extension * ext, char * pref) :
162 Gtk::Adjustment(0.0, 0.0, 10.0, 0.1), _ext(ext), _pref(pref) {
163 this->set_value(_ext->get_param_float(_pref));
164 this->signal_value_changed().connect(sigc::mem_fun(this, &PrefAdjustment::val_changed));
165 return;
166 };
168 void val_changed (void);
169 }; /* class PrefAdjustment */
171 /** \brief A function to respond to the value_changed signal from the
172 adjustment.
174 This function just grabs the value from the adjustment and writes
175 it to the parameter. Very simple, but yet beautiful.
176 */
177 void
178 PrefAdjustment::val_changed (void)
179 {
180 // std::cout << "Value Changed to: " << this->get_value() << std::endl;
181 _ext->set_param_float(_pref, this->get_value());
182 return;
183 }
185 /** \brief A function to get the prefences for the grid
186 \param moudule Module which holds the params
187 \param view Unused today - may get style information in the future.
189 This function builds a VBox, and puts it into a Gtk::Plug. This way
190 the native window pointer can be pulled out and returned up to be
191 stuck in a Gtk::Socket further up the call stack. In the Vbox there
192 are several Hboxes, each one being a spin button to adjust a particular
193 parameter. The names of the parameters and the labels are all
194 stored in the arrays in the middle of the function. This makes
195 the code very generic. This will probably have to change if someone
196 wants to make this dialog look nicer.
197 */
198 Gtk::Widget *
199 Grid::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View * view)
200 {
201 Gtk::VBox * vbox;
202 vbox = new Gtk::VBox();
204 #define NUM_PREFERENCES 5
205 char * labels[NUM_PREFERENCES] = {N_("Line Width"),
206 N_("Horizontal Spacing"),
207 N_("Vertical Spacing"),
208 N_("Horizontal Offset"),
209 N_("Vertical Offset")};
210 char * prefs[NUM_PREFERENCES] = {"lineWidth",
211 "xspacing",
212 "yspacing",
213 "xoffset",
214 "yoffset"};
216 for (int i = 0; i < NUM_PREFERENCES; i++) {
217 Gtk::HBox * hbox = new Gtk::HBox();
219 Gtk::Label * label = new Gtk::Label(_(labels[i]), Gtk::ALIGN_LEFT);
220 label->show();
221 hbox->pack_start(*label, true, true);
223 PrefAdjustment * pref = new PrefAdjustment(module, prefs[i]);
225 Gtk::SpinButton * spin = new Gtk::SpinButton(*pref, 0.1, 1);
226 spin->show();
227 hbox->pack_start(*spin, false, false);
229 hbox->show();
231 vbox->pack_start(*hbox, true, true);
232 }
233 #undef NUM_PREFERENCES
235 vbox->show();
237 return vbox;
238 }
240 #include "clear-n_.h"
242 void
243 Grid::init (void)
244 {
245 Inkscape::Extension::build_from_mem(
246 "<inkscape-extension>\n"
247 "<name>" N_("Grid") "</name>\n"
248 "<id>org.inkscape.effect.grid</id>\n"
249 "<param name=\"lineWidth\" type=\"float\">1.0</param>\n"
250 "<param name=\"xspacing\" type=\"float\">10.0</param>\n"
251 "<param name=\"yspacing\" type=\"float\">10.0</param>\n"
252 "<param name=\"xoffset\" type=\"float\">5.0</param>\n"
253 "<param name=\"yoffset\" type=\"float\">5.0</param>\n"
254 "<effect>\n"
255 "<object-type>all</object-type>\n"
256 "<effects-menu>\n"
257 "<submenu name=\"" N_("Render") "\" />\n"
258 "</effects-menu>\n"
259 "</effect>\n"
260 "</inkscape-extension>\n", new Grid());
261 return;
262 }
264 }; /* namespace Internal */
265 }; /* namespace Extension */
266 }; /* namespace Inkscape */
268 /*
269 Local Variables:
270 mode:c++
271 c-file-style:"stroustrup"
272 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
273 indent-tabs-mode:nil
274 fill-column:99
275 End:
276 */
277 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :