3 * gnm-so-polygon.c: Polygons
5 * Copyright (C) 2005 Jody Goldberg (jody@gnome.org)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) version 3.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 #include <gnumeric-config.h>
25 #include <gnm-so-polygon.h>
26 #include <sheet-object-impl.h>
28 #include <parse-util.h>
30 #include <goffice/goffice.h>
31 #include <gsf/gsf-impl-utils.h>
32 #include <glib/gi18n-lib.h>
36 #define GNM_SO_POLYGON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SO_POLYGON_TYPE, GnmSOPolygon))
37 #define GNM_SO_POLYGON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GNM_SO_POLYGON_TYPE, GnmSOPolygonClass))
44 typedef SheetObjectClass GnmSOPolygonClass
;
49 so_polygon_view_set_bounds (SheetObjectView
*sov
, double const *coords
, gboolean visible
)
51 GocItem
*view
= GOC_ITEM (sov
->base
.children
->data
);
54 SheetObject
*so
= sheet_object_view_get_so (sov
);
55 GnmSOPolygon
const *sop
= GNM_SO_POLYGON (so
);
58 double x_scale
, y_scale
, x_translate
, y_translate
;
61 if (sop
->points
== NULL
)
64 n
= sop
->points
->len
/ 2;
68 pts
= goc_points_new (n
);
69 x_scale
= fabs (coords
[2] - coords
[0]);
70 y_scale
= fabs (coords
[3] - coords
[1]);
71 x_translate
= MIN (coords
[0], coords
[2]),
72 y_translate
= MIN (coords
[1], coords
[3]);
74 src
= &g_array_index (sop
->points
, double, 0);
75 for (i
= 0 ; i
< n
; src
+= 2, i
++) {
76 pts
->points
[i
].x
= x_translate
+ x_scale
* src
[0];
77 pts
->points
[i
].y
= y_translate
+ y_scale
* src
[1];
80 goc_item_set (view
, "points", pts
, NULL
);
81 goc_points_unref (pts
);
82 goc_item_show (GOC_ITEM (view
));
84 goc_item_hide (GOC_ITEM (view
));
88 so_polygon_goc_view_class_init (SheetObjectViewClass
*sov_klass
)
90 sov_klass
->set_bounds
= so_polygon_view_set_bounds
;
93 typedef SheetObjectView PolygonGocView
;
94 typedef SheetObjectViewClass PolygonGocViewClass
;
95 static GSF_CLASS (PolygonGocView
, so_polygon_goc_view
,
96 so_polygon_goc_view_class_init
, NULL
,
99 #endif /* GNM_WITH_GTK */
101 /*****************************************************************************/
103 static SheetObjectClass
*gnm_so_polygon_parent_class
;
112 sop_default_style (void)
114 GOStyle
*res
= go_style_new ();
115 res
->interesting_fields
= GO_STYLE_OUTLINE
| GO_STYLE_FILL
;
116 res
->line
.width
= 0; /* hairline */
117 res
->line
.color
= GO_COLOR_BLACK
;
118 res
->line
.dash_type
= GO_LINE_SOLID
; /* anything but 0 */
119 res
->line
.join
= CAIRO_LINE_JOIN_ROUND
;
120 res
->fill
.type
= GO_STYLE_FILL_PATTERN
;
121 go_pattern_set_solid (&res
->fill
.pattern
, GO_COLOR_WHITE
);
126 #include <sheet-control-gui.h>
127 #include <dialogs/dialogs.h>
130 cb_gnm_so_polygon_style_changed (GocItem
*view
, GnmSOPolygon
const *sop
)
132 GocItem
*item
= GOC_ITEM (GOC_GROUP (view
)->children
->data
);
133 GOStyle
const *style
= sop
->style
;
134 goc_item_set (item
, "style", style
, NULL
);
137 static SheetObjectView
*
138 gnm_so_polygon_new_view (SheetObject
*so
, SheetObjectViewContainer
*container
)
140 GnmSOPolygon
*sop
= GNM_SO_POLYGON (so
);
141 GocItem
*item
= goc_item_new (
142 gnm_pane_object_group (GNM_PANE (container
)),
143 so_polygon_goc_view_get_type (),
145 goc_item_new (GOC_GROUP (item
),
148 cb_gnm_so_polygon_style_changed (item
, sop
);
149 g_signal_connect_object (sop
,
150 "notify::style", G_CALLBACK (cb_gnm_so_polygon_style_changed
),
152 return gnm_pane_object_register (so
, item
, TRUE
);
156 gnm_so_polygon_user_config (SheetObject
*so
, SheetControl
*sc
)
158 dialog_so_styled (scg_wbcg (GNM_SCG (sc
)), G_OBJECT (so
),
159 sop_default_style (),
160 _("Polygon Properties"), SO_STYLED_STYLE_ONLY
);
163 #endif /* GNM_WITH_GTK */
166 gnm_so_polygon_draw_cairo (SheetObject
const *so
, cairo_t
*cr
,
167 double width
, double height
)
172 gnm_so_polygon_write_xml_sax (SheetObject
const *so
, GsfXMLOut
*output
,
173 GnmConventions
const *convs
)
175 GnmSOPolygon
const *sop
= GNM_SO_POLYGON (so
);
178 for (ui
= 0; ui
+ 1 < (sop
->points
? sop
->points
->len
: 0); ui
+= 2) {
179 double x
= g_array_index (sop
->points
, double, ui
);
180 double y
= g_array_index (sop
->points
, double, ui
+ 1);
181 gsf_xml_out_start_element (output
, "Point");
182 go_xml_out_add_double (output
, "x", x
);
183 go_xml_out_add_double (output
, "y", y
);
184 gsf_xml_out_end_element (output
); /* </Point> */
187 gsf_xml_out_start_element (output
, "Style");
188 go_persist_sax_save (GO_PERSIST (sop
->style
), output
);
189 gsf_xml_out_end_element (output
); /* </Style> */
193 gnm_so_polygon_copy (SheetObject
*dst
, SheetObject
const *src
)
195 GnmSOPolygon
const *sop
= GNM_SO_POLYGON (src
);
196 GnmSOPolygon
*new_sop
= GNM_SO_POLYGON (dst
);
197 unsigned i
= sop
->points
->len
;
199 g_array_set_size (new_sop
->points
, i
);
201 g_array_index (new_sop
->points
, double, i
) =
202 g_array_index (sop
->points
, double, i
);
203 gnm_so_polygon_parent_class
->copy (dst
, src
);
207 gnm_so_polygon_set_property (GObject
*obj
, guint param_id
,
208 GValue
const *value
, GParamSpec
*pspec
)
210 GnmSOPolygon
*sop
= GNM_SO_POLYGON (obj
);
214 case SOP_PROP_STYLE
: {
215 GOStyle
*style
= go_style_dup (g_value_get_object (value
));
216 style
->interesting_fields
= GO_STYLE_OUTLINE
| GO_STYLE_FILL
;
217 g_object_unref (sop
->style
);
221 case SOP_PROP_POINTS
:
222 points
= g_value_get_pointer (value
);
224 points
= g_array_new (FALSE
, TRUE
, sizeof (double));
226 if (sop
->points
!= points
) {
227 g_array_free (sop
->points
, TRUE
);
228 sop
->points
= points
;
233 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj
, param_id
, pspec
);
239 gnm_so_polygon_get_property (GObject
*obj
, guint param_id
,
240 GValue
*value
, GParamSpec
*pspec
)
242 GnmSOPolygon
*sop
= GNM_SO_POLYGON (obj
);
245 g_value_set_object (value
, sop
->style
);
247 case SOP_PROP_POINTS
:
248 g_value_set_pointer (value
, sop
->points
);
250 case SOP_PROP_DOCUMENT
:
251 g_value_set_object (value
, sheet_object_get_sheet (GNM_SO (obj
))->workbook
);
254 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj
, param_id
, pspec
);
260 gnm_so_polygon_finalize (GObject
*object
)
262 GnmSOPolygon
*sop
= GNM_SO_POLYGON (object
);
264 g_object_unref (sop
->style
);
266 if (sop
->points
!= NULL
) {
267 g_array_free (sop
->points
, TRUE
);
270 G_OBJECT_CLASS (gnm_so_polygon_parent_class
)->finalize (object
);
274 gnm_so_polygon_class_init (GObjectClass
*gobject_class
)
276 SheetObjectClass
*so_class
= GNM_SO_CLASS (gobject_class
);
278 gnm_so_polygon_parent_class
= g_type_class_peek_parent (gobject_class
);
280 gobject_class
->finalize
= gnm_so_polygon_finalize
;
281 gobject_class
->set_property
= gnm_so_polygon_set_property
;
282 gobject_class
->get_property
= gnm_so_polygon_get_property
;
283 so_class
->write_xml_sax
= gnm_so_polygon_write_xml_sax
;
284 so_class
->copy
= gnm_so_polygon_copy
;
285 so_class
->rubber_band_directly
= FALSE
;
286 so_class
->xml_export_name
= "SheetObjectPolygon";
289 so_class
->new_view
= gnm_so_polygon_new_view
;
290 so_class
->user_config
= gnm_so_polygon_user_config
;
291 #endif /* GNM_WITH_GTK */
292 so_class
->draw_cairo
= gnm_so_polygon_draw_cairo
;
294 g_object_class_install_property (gobject_class
, SOP_PROP_STYLE
,
295 g_param_spec_object ("style", NULL
, NULL
, GO_TYPE_STYLE
,
296 GSF_PARAM_STATIC
| G_PARAM_READWRITE
));
297 g_object_class_install_property (gobject_class
, SOP_PROP_POINTS
,
298 g_param_spec_pointer ("points", NULL
, NULL
,
299 GSF_PARAM_STATIC
| G_PARAM_READWRITE
));
300 g_object_class_install_property (gobject_class
, SOP_PROP_DOCUMENT
,
301 g_param_spec_object ("document", NULL
, NULL
, GO_TYPE_DOC
,
302 GSF_PARAM_STATIC
| G_PARAM_READABLE
));
306 gnm_so_polygon_init (GObject
*obj
)
308 static double const initial_coords
[] = {
312 GnmSOPolygon
*sop
= GNM_SO_POLYGON (obj
);
313 sop
->points
= g_array_sized_new (FALSE
, TRUE
, sizeof (double),
314 G_N_ELEMENTS (initial_coords
));
315 sop
->style
= sop_default_style ();
316 g_array_append_vals (sop
->points
,
317 initial_coords
, G_N_ELEMENTS (initial_coords
));
320 GSF_CLASS (GnmSOPolygon
, gnm_so_polygon
,
321 gnm_so_polygon_class_init
, gnm_so_polygon_init
,