Whitespace.
[gnumeric.git] / src / gnm-so-polygon.c
blob365819ef9769c97be216f9ea96fa3d3936a903e0
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /*
4 * gnm-so-polygon.c: Polygons
6 * Copyright (C) 2005 Jody Goldberg (jody@gnome.org)
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) version 3.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21 * USA
24 #include <gnumeric-config.h>
25 #include "gnumeric.h"
26 #include "gnm-so-polygon.h"
27 #include "sheet-object-impl.h"
28 #include "sheet.h"
29 #include "parse-util.h"
31 #include <goffice/goffice.h>
32 #include <gsf/gsf-impl-utils.h>
33 #include <glib/gi18n-lib.h>
34 #include <string.h>
35 #include <math.h>
37 #define GNM_SO_POLYGON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SO_POLYGON_TYPE, GnmSOPolygon))
38 #define GNM_SO_POLYGON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GNM_SO_POLYGON_TYPE, GnmSOPolygonClass))
40 typedef struct {
41 SheetObject base;
42 GOStyle *style;
43 GArray *points;
44 } GnmSOPolygon;
45 typedef SheetObjectClass GnmSOPolygonClass;
47 #ifdef GNM_WITH_GTK
48 #include "gnm-pane.h"
49 static void
50 so_polygon_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible)
52 GocItem *view = GOC_ITEM (sov->base.children->data);
54 if (visible) {
55 SheetObject *so = sheet_object_view_get_so (sov);
56 GnmSOPolygon const *sop = GNM_SO_POLYGON (so);
57 unsigned i, n;
58 GocPoints *pts;
59 double x_scale, y_scale, x_translate, y_translate;
60 double const *src;
62 if (sop->points == NULL)
63 return;
65 n = sop->points->len / 2;
66 if (n == 0)
67 return;
69 pts = goc_points_new (n);
70 x_scale = fabs (coords[2] - coords[0]);
71 y_scale = fabs (coords[3] - coords[1]);
72 x_translate = MIN (coords[0], coords[2]),
73 y_translate = MIN (coords[1], coords[3]);
75 src = &g_array_index (sop->points, double, 0);
76 for (i = 0 ; i < n; src += 2, i++) {
77 pts->points[i].x = x_translate + x_scale * src[0];
78 pts->points[i].y = y_translate + y_scale * src[1];
81 goc_item_set (view, "points", pts, NULL);
82 goc_points_unref (pts);
83 goc_item_show (GOC_ITEM (view));
84 } else
85 goc_item_hide (GOC_ITEM (view));
88 static void
89 so_polygon_goc_view_class_init (SheetObjectViewClass *sov_klass)
91 sov_klass->set_bounds = so_polygon_view_set_bounds;
94 typedef SheetObjectView PolygonGocView;
95 typedef SheetObjectViewClass PolygonGocViewClass;
96 static GSF_CLASS (PolygonGocView, so_polygon_goc_view,
97 so_polygon_goc_view_class_init, NULL,
98 GNM_SO_VIEW_TYPE)
100 #endif /* GNM_WITH_GTK */
102 /*****************************************************************************/
104 static SheetObjectClass *gnm_so_polygon_parent_class;
105 enum {
106 SOP_PROP_0,
107 SOP_PROP_STYLE,
108 SOP_PROP_POINTS,
109 SOP_PROP_DOCUMENT
112 static GOStyle *
113 sop_default_style (void)
115 GOStyle *res = go_style_new ();
116 res->interesting_fields = GO_STYLE_OUTLINE | GO_STYLE_FILL;
117 res->line.width = 0; /* hairline */
118 res->line.color = GO_COLOR_BLACK;
119 res->line.dash_type = GO_LINE_SOLID; /* anything but 0 */
120 res->line.join = CAIRO_LINE_JOIN_ROUND;
121 res->fill.type = GO_STYLE_FILL_PATTERN;
122 go_pattern_set_solid (&res->fill.pattern, GO_COLOR_WHITE);
123 return res;
126 #ifdef GNM_WITH_GTK
127 #include <sheet-control-gui.h>
128 #include <dialogs/dialogs.h>
130 static void
131 cb_gnm_so_polygon_style_changed (GocItem *view, GnmSOPolygon const *sop)
133 GocItem *item = GOC_ITEM (GOC_GROUP (view)->children->data);
134 GOStyle const *style = sop->style;
135 goc_item_set (item, "style", style, NULL);
138 static SheetObjectView *
139 gnm_so_polygon_new_view (SheetObject *so, SheetObjectViewContainer *container)
141 GnmSOPolygon *sop = GNM_SO_POLYGON (so);
142 GocItem *item = goc_item_new (
143 gnm_pane_object_group (GNM_PANE (container)),
144 so_polygon_goc_view_get_type (),
145 NULL);
146 goc_item_new (GOC_GROUP (item),
147 GOC_TYPE_POLYGON,
148 NULL);
149 cb_gnm_so_polygon_style_changed (item, sop);
150 g_signal_connect_object (sop,
151 "notify::style", G_CALLBACK (cb_gnm_so_polygon_style_changed),
152 item, 0);
153 return gnm_pane_object_register (so, item, TRUE);
156 static void
157 gnm_so_polygon_user_config (SheetObject *so, SheetControl *sc)
159 dialog_so_styled (scg_wbcg (GNM_SCG (sc)), G_OBJECT (so),
160 sop_default_style (),
161 _("Polygon Properties"), SO_STYLED_STYLE_ONLY);
164 #endif /* GNM_WITH_GTK */
166 static void
167 gnm_so_polygon_draw_cairo (SheetObject const *so, cairo_t *cr,
168 double width, double height)
172 static void
173 gnm_so_polygon_write_xml_sax (SheetObject const *so, GsfXMLOut *output,
174 GnmConventions const *convs)
176 GnmSOPolygon const *sop = GNM_SO_POLYGON (so);
177 unsigned int ui;
179 for (ui = 0; ui + 1 < (sop->points ? sop->points->len : 0); ui += 2) {
180 double x = g_array_index (sop->points, double, ui);
181 double y = g_array_index (sop->points, double, ui + 1);
182 gsf_xml_out_start_element (output, "Point");
183 go_xml_out_add_double (output, "x", x);
184 go_xml_out_add_double (output, "y", y);
185 gsf_xml_out_end_element (output); /* </Point> */
188 gsf_xml_out_start_element (output, "Style");
189 go_persist_sax_save (GO_PERSIST (sop->style), output);
190 gsf_xml_out_end_element (output); /* </Style> */
193 static void
194 gnm_so_polygon_copy (SheetObject *dst, SheetObject const *src)
196 GnmSOPolygon const *sop = GNM_SO_POLYGON (src);
197 GnmSOPolygon *new_sop = GNM_SO_POLYGON (dst);
198 unsigned i = sop->points->len;
200 g_array_set_size (new_sop->points, i);
201 while (i-- > 0)
202 g_array_index (new_sop->points, double, i) =
203 g_array_index (sop->points, double, i);
204 gnm_so_polygon_parent_class->copy (dst, src);
207 static void
208 gnm_so_polygon_set_property (GObject *obj, guint param_id,
209 GValue const *value, GParamSpec *pspec)
211 GnmSOPolygon *sop = GNM_SO_POLYGON (obj);
212 GArray *points;
214 switch (param_id) {
215 case SOP_PROP_STYLE: {
216 GOStyle *style = go_style_dup (g_value_get_object (value));
217 style->interesting_fields = GO_STYLE_OUTLINE | GO_STYLE_FILL;
218 g_object_unref (sop->style);
219 sop->style = style;
220 break;
222 case SOP_PROP_POINTS:
223 points = g_value_get_pointer (value);
224 if (!points)
225 points = g_array_new (FALSE, TRUE, sizeof (double));
227 if (sop->points != points) {
228 g_array_free (sop->points, TRUE);
229 sop->points = points;
231 break;
233 default:
234 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
235 return;
239 static void
240 gnm_so_polygon_get_property (GObject *obj, guint param_id,
241 GValue *value, GParamSpec *pspec)
243 GnmSOPolygon *sop = GNM_SO_POLYGON (obj);
244 switch (param_id) {
245 case SOP_PROP_STYLE:
246 g_value_set_object (value, sop->style);
247 break;
248 case SOP_PROP_POINTS:
249 g_value_set_pointer (value, sop->points);
250 break;
251 case SOP_PROP_DOCUMENT:
252 g_value_set_object (value, sheet_object_get_sheet (GNM_SO (obj))->workbook);
253 break;
254 default:
255 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
256 break;
260 static void
261 gnm_so_polygon_finalize (GObject *object)
263 GnmSOPolygon *sop = GNM_SO_POLYGON (object);
265 g_object_unref (sop->style);
266 sop->style = NULL;
267 if (sop->points != NULL) {
268 g_array_free (sop->points, TRUE);
269 sop->points = NULL;
271 G_OBJECT_CLASS (gnm_so_polygon_parent_class)->finalize (object);
274 static void
275 gnm_so_polygon_class_init (GObjectClass *gobject_class)
277 SheetObjectClass *so_class = GNM_SO_CLASS (gobject_class);
279 gnm_so_polygon_parent_class = g_type_class_peek_parent (gobject_class);
281 gobject_class->finalize = gnm_so_polygon_finalize;
282 gobject_class->set_property = gnm_so_polygon_set_property;
283 gobject_class->get_property = gnm_so_polygon_get_property;
284 so_class->write_xml_sax = gnm_so_polygon_write_xml_sax;
285 so_class->copy = gnm_so_polygon_copy;
286 so_class->rubber_band_directly = FALSE;
287 so_class->xml_export_name = "SheetObjectPolygon";
289 #ifdef GNM_WITH_GTK
290 so_class->new_view = gnm_so_polygon_new_view;
291 so_class->user_config = gnm_so_polygon_user_config;
292 #endif /* GNM_WITH_GTK */
293 so_class->draw_cairo = gnm_so_polygon_draw_cairo;
295 g_object_class_install_property (gobject_class, SOP_PROP_STYLE,
296 g_param_spec_object ("style", NULL, NULL, GO_TYPE_STYLE,
297 GSF_PARAM_STATIC | G_PARAM_READWRITE));
298 g_object_class_install_property (gobject_class, SOP_PROP_POINTS,
299 g_param_spec_pointer ("points", NULL, NULL,
300 GSF_PARAM_STATIC | G_PARAM_READWRITE));
301 g_object_class_install_property (gobject_class, SOP_PROP_DOCUMENT,
302 g_param_spec_object ("document", NULL, NULL, GO_TYPE_DOC,
303 GSF_PARAM_STATIC | G_PARAM_READABLE));
306 static void
307 gnm_so_polygon_init (GObject *obj)
309 static double const initial_coords [] = {
310 0., 0., 1., 0.,
311 1., 1., 0., 1.
313 GnmSOPolygon *sop = GNM_SO_POLYGON (obj);
314 sop->points = g_array_sized_new (FALSE, TRUE, sizeof (double),
315 G_N_ELEMENTS (initial_coords));
316 sop->style = sop_default_style ();
317 g_array_append_vals (sop->points,
318 initial_coords, G_N_ELEMENTS (initial_coords));
321 GSF_CLASS (GnmSOPolygon, gnm_so_polygon,
322 gnm_so_polygon_class_init, gnm_so_polygon_init,
323 GNM_SO_TYPE)