1 /*
2 * gog-smoothed-curve.c :
3 *
4 * Copyright (C) 2006 Jean Brefort (jean.brefort@normalesup.org)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 */
21
22 #include <goffice/goffice-config.h>
23 #include <goffice/goffice.h>
24
25 #include <gsf/gsf-impl-utils.h>
26 #include <glib/gi18n-lib.h>
27
28 static GType gog_smoothed_curve_view_get_type (void);
29
30 static GObjectClass *smoothed_curve_parent_klass;
31
32 /**
33 * GogSmoothedCurveClass:
34 * @base: base class.
35 * @max_dim: number of #GOData parameters.
36 *
37 * Base class for smoothed curves.
38 **/
39 #ifdef GOFFICE_WITH_GTK
40 static void
gog_smoothed_curve_populate_editor(GogObject * gobj,GOEditor * editor,GogDataAllocator * dalloc,GOCmdContext * cc)41 gog_smoothed_curve_populate_editor (GogObject *gobj,
42 GOEditor *editor,
43 GogDataAllocator *dalloc,
44 GOCmdContext *cc)
45 {
46 GtkWidget *w, *child;
47 GtkGrid *grid;
48 GogDataset *set = GOG_DATASET (gobj);
49
50 w = gtk_grid_new ();
51 grid = GTK_GRID (w);
52 g_object_set (G_OBJECT (grid), "margin", 12, "column-spacing", 12,
53 "orientation", GTK_ORIENTATION_VERTICAL, NULL);
54 child = gtk_label_new (_("(Name):"));
55 gtk_grid_attach (grid, child, 0, 0, 1, 1);
56 child = GTK_WIDGET (gog_data_allocator_editor (dalloc, set, -1, GOG_DATA_SCALAR));
57 g_object_set (G_OBJECT (child), "hexpand", TRUE, NULL);
58 gtk_grid_attach (grid, child, 1, 0, 1, 1);
59 gtk_widget_show_all (w);
60 go_editor_add_page (editor, w, _("Details"));
61
62 (GOG_OBJECT_CLASS (smoothed_curve_parent_klass)->populate_editor) (gobj, editor, dalloc, cc);
63 }
64 #endif
65
66 static void
gog_smoothed_curve_init_style(GogStyledObject * gso,GOStyle * style)67 gog_smoothed_curve_init_style (GogStyledObject *gso, GOStyle *style)
68 {
69 style->interesting_fields = GO_STYLE_LINE;
70 gog_theme_fillin_style (gog_object_get_theme (GOG_OBJECT (gso)),
71 style, GOG_OBJECT (gso), 0, GO_STYLE_LINE);
72 }
73
74 static void
gog_smoothed_curve_finalize(GObject * obj)75 gog_smoothed_curve_finalize (GObject *obj)
76 {
77 GogSmoothedCurve *curve = GOG_SMOOTHED_CURVE (obj);
78 g_free (curve->x);
79 g_free (curve->y);
80 if (curve->name != NULL) {
81 gog_dataset_finalize (GOG_DATASET (obj));
82 g_free (curve->name); /* aliased pointer */
83 curve->name = NULL;
84 }
85 (*smoothed_curve_parent_klass->finalize) (obj);
86 }
87
88 static char const *
gog_smoothed_curve_type_name(GogObject const * gobj)89 gog_smoothed_curve_type_name (GogObject const *gobj)
90 {
91 return N_("Smoothed Curve");
92 }
93
94 static void
gog_smoothed_curve_parent_changed(GogObject * obj,G_GNUC_UNUSED gboolean was_set)95 gog_smoothed_curve_parent_changed (GogObject *obj, G_GNUC_UNUSED gboolean was_set)
96 {
97 GogSmoothedCurve *sc = GOG_SMOOTHED_CURVE (obj);
98 if (sc->name == NULL) {
99 GogSmoothedCurveClass *klass = (GogSmoothedCurveClass *) G_OBJECT_GET_CLASS (obj);
100 sc->name = g_new0 (GogDatasetElement, klass->max_dim + 2);
101 }
102 GOG_OBJECT_CLASS (smoothed_curve_parent_klass)->parent_changed (obj, was_set);
103 }
104
105 static void
gog_smoothed_curve_class_init(GogObjectClass * gog_klass)106 gog_smoothed_curve_class_init (GogObjectClass *gog_klass)
107 {
108 GObjectClass *gobject_klass = (GObjectClass *) gog_klass;
109 GogStyledObjectClass *style_klass = (GogStyledObjectClass *) gog_klass;
110 GogSmoothedCurveClass *curve_klass = (GogSmoothedCurveClass *) gog_klass;
111 smoothed_curve_parent_klass = g_type_class_peek_parent (gog_klass);
112
113 gobject_klass->finalize = gog_smoothed_curve_finalize;
114
115 curve_klass->max_dim = -1;
116 style_klass->init_style = gog_smoothed_curve_init_style;
117 gog_klass->type_name = gog_smoothed_curve_type_name;
118 gog_klass->parent_changed = gog_smoothed_curve_parent_changed;
119 gog_klass->view_type = gog_smoothed_curve_view_get_type ();
120
121 #ifdef GOFFICE_WITH_GTK
122 gog_klass->populate_editor = gog_smoothed_curve_populate_editor;
123 #endif
124 }
125
126 static void
gog_smoothed_curve_init(GogSmoothedCurve * curve)127 gog_smoothed_curve_init (GogSmoothedCurve *curve)
128 {
129 curve->nb = 0;
130 curve->x = curve->y = NULL;
131 }
132
133 static void
gog_smoothed_curve_dataset_dims(GogDataset const * set,int * first,int * last)134 gog_smoothed_curve_dataset_dims (GogDataset const *set, int *first, int *last)
135 {
136 GogSmoothedCurveClass *klass = (GogSmoothedCurveClass *) G_OBJECT_GET_CLASS (set);
137
138 *first = -1;
139 *last = klass->max_dim;
140 }
141
142 static GogDatasetElement *
gog_smoothed_curve_dataset_get_elem(GogDataset const * set,int dim_i)143 gog_smoothed_curve_dataset_get_elem (GogDataset const *set, int dim_i)
144 {
145 GogSmoothedCurve const *sc = GOG_SMOOTHED_CURVE (set);
146 GogSmoothedCurveClass *klass = (GogSmoothedCurveClass *) G_OBJECT_GET_CLASS (set);
147 g_return_val_if_fail (dim_i >= -1 && dim_i <= klass->max_dim, NULL);
148 dim_i++;
149 return sc->name + dim_i;
150 }
151
152 static void
gog_smoothed_curve_dataset_dim_changed(GogDataset * set,int dim_i)153 gog_smoothed_curve_dataset_dim_changed (GogDataset *set, int dim_i)
154 {
155 GogSmoothedCurveClass *klass = (GogSmoothedCurveClass *) G_OBJECT_GET_CLASS (set);
156 g_return_if_fail (dim_i >= -1 && dim_i <= klass->max_dim);
157 {
158 GogSmoothedCurve const *sc = GOG_SMOOTHED_CURVE (set);
159 if (dim_i == -1) {
160 GOData *name_src = sc->name->data;
161 char *name = (name_src != NULL)
162 ? go_data_get_scalar_string (name_src) : NULL;
163 gog_object_set_name (GOG_OBJECT (set), name, NULL);
164 } else
165 gog_object_request_update (GOG_OBJECT (set));
166 }
167 }
168
169 static void
gog_smoothed_curve_dataset_init(GogDatasetClass * iface)170 gog_smoothed_curve_dataset_init (GogDatasetClass *iface)
171 {
172 iface->get_elem = gog_smoothed_curve_dataset_get_elem;
173 iface->dims = gog_smoothed_curve_dataset_dims;
174 iface->dim_changed = gog_smoothed_curve_dataset_dim_changed;
175 }
176
177 GSF_CLASS_FULL (GogSmoothedCurve, gog_smoothed_curve,
178 NULL, NULL, gog_smoothed_curve_class_init, NULL,
179 gog_smoothed_curve_init, GOG_TYPE_TREND_LINE, G_TYPE_FLAG_ABSTRACT,
180 GSF_INTERFACE (gog_smoothed_curve_dataset_init, GOG_TYPE_DATASET))
181
182 /****************************************************************************/
183
184 typedef GogView GogSmoothedCurveView;
185 typedef GogViewClass GogSmoothedCurveViewClass;
186
187 #define GOG_TYPE_SMOOTHED_CURVE_VIEW (gog_smoothed_curve_view_get_type ())
188 #define GOG_SMOOTHED_CURVE_VIEW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_TYPE_SMOOTHED_CURVE_VIEW, GogSmoothedCurveView))
189 #define GOG_IS_SMOOTHED_CURVE_VIEW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_TYPE_SMOOTHED_CURVE_VIEW))
190
191 /*static GogViewClass *smoothed_curve_view_parent_klass; */
192
193 static void
gog_smoothed_curve_view_render(GogView * view,GogViewAllocation const * bbox)194 gog_smoothed_curve_view_render (GogView *view, GogViewAllocation const *bbox)
195 {
196 GogSmoothedCurve *curve = GOG_SMOOTHED_CURVE (view->model);
197 GogSeries *series = GOG_SERIES ((GOG_OBJECT (curve))->parent);
198 GogPlot *plot = series->plot;
199 GogChart *chart = GOG_CHART (GOG_OBJECT (plot)->parent);
200 GogChartMap *chart_map;
201 GOStyle *style;
202 GOPath *path;
203
204 if (curve->nb == 0 || curve->x == NULL || curve->y == NULL)
205 return;
206
207 chart_map = gog_chart_map_new (chart, &view->residual,
208 plot->axis[GOG_AXIS_X],
209 plot->axis[GOG_AXIS_Y],
210 NULL, FALSE);
211 if (!gog_chart_map_is_valid (chart_map)) {
212 gog_chart_map_free (chart_map);
213 return;
214 }
215
216 gog_renderer_push_clip_rectangle (view->renderer, view->residual.x, view->residual.y,
217 view->residual.w, view->residual.h);
218
219 path = gog_chart_map_make_path (chart_map, curve->x, curve->y, curve->nb, GO_LINE_INTERPOLATION_LINEAR, FALSE, NULL);
220 style = GOG_STYLED_OBJECT (curve)->style;
221 gog_renderer_push_style (view->renderer, style);
222 gog_renderer_stroke_serie (view->renderer, path);
223 gog_renderer_pop_style (view->renderer);
224 go_path_free (path);
225 gog_renderer_pop_clip (view->renderer);
226
227 gog_chart_map_free (chart_map);
228 }
229
230 static void
gog_smoothed_curve_view_class_init(GogSmoothedCurveViewClass * gview_klass)231 gog_smoothed_curve_view_class_init (GogSmoothedCurveViewClass *gview_klass)
232 {
233 GogViewClass *view_klass = (GogViewClass *) gview_klass;
234
235 view_klass->render = gog_smoothed_curve_view_render;
236 }
237
238 static GSF_CLASS (GogSmoothedCurveView, gog_smoothed_curve_view,
239 gog_smoothed_curve_view_class_init, NULL,
240 GOG_TYPE_VIEW)
241