Code

r11472@tres: ted | 2006-04-22 20:32:45 -0700
[inkscape.git] / src / extension / internal / grid.cpp
1 /**
2     \file grid.cpp
3  
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;
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)
180     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
181     _ext->set_param_float(_pref, this->get_value());
182     return;
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)
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;
240 #include "clear-n_.h"
242 void
243 Grid::init (void)
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;
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 :