~ubuntu-branches/ubuntu/karmic/mergeant/karmic

« back to all changes in this revision

Viewing changes to libmergeant/graph/mg-canvas-entity.c

  • Committer: Bazaar Package Importer
  • Author(s): Gustavo R. Montesino
  • Date: 2007-11-29 08:44:48 UTC
  • mfrom: (2.1.4 hardy)
  • Revision ID: james.westby@ubuntu.com-20071129084448-6aon73d22bv6hzfw
Tags: 0.67-3
* Re-enable installation of the mime files in mergeant.install
* mergeant.dirs: create usr/share/mime/packages to make dh_installmime add
  the update-mime-database code snippets

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* mg-canvas-entity.c
2
 
 *
3
 
 * Copyright (C) 2002 - 2004 Vivien Malerba
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU General Public License as
7
 
 * published by the Free Software Foundation; either version 2 of the
8
 
 * License, or (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18
 
 * USA
19
 
 */
20
 
 
21
 
#include "mg-canvas.h"
22
 
#include "mg-canvas-entity.h"
23
 
#include "mg-canvas-field.h"
24
 
#include <libmergeant/mg-field.h>
25
 
#include <libmergeant/mg-db-table.h>
26
 
#include <libmergeant/mg-query.h>
27
 
#include <libmergeant/mg-entity.h>
28
 
 
29
 
static void mg_canvas_entity_class_init (MgCanvasEntityClass * class);
30
 
static void mg_canvas_entity_init       (MgCanvasEntity * drag);
31
 
static void mg_canvas_entity_dispose    (GObject   * object);
32
 
static void mg_canvas_entity_finalize   (GObject   * object);
33
 
 
34
 
static void mg_canvas_entity_set_property (GObject              *object,
35
 
                                           guint                 param_id,
36
 
                                           const GValue         *value,
37
 
                                           GParamSpec           *pspec);
38
 
static void mg_canvas_entity_get_property (GObject              *object,
39
 
                                           guint                 param_id,
40
 
                                           GValue               *value,
41
 
                                           GParamSpec           *pspec);
42
 
 
43
 
enum
44
 
{
45
 
        PROP_0,
46
 
        PROP_ENTITY,
47
 
        PROP_SCALE
48
 
};
49
 
 
50
 
struct _MgCanvasEntityPrivate
51
 
{
52
 
        MgEntity           *entity;
53
 
 
54
 
        /* UI building information */
55
 
        GSList             *field_items; /* list of GnomeCanvasItem for the fields */
56
 
        gint                init_font_size;
57
 
        GnomeCanvasItem    *title;
58
 
        gdouble            *field_ypos; /* array for each field's Y position in this canvas group */
59
 
 
60
 
        /* presentation parameters */
61
 
        gdouble             x_text_space;
62
 
        gdouble             y_text_space;
63
 
};
64
 
 
65
 
/* get a pointer to the parents to be able to call their destructor */
66
 
static GObjectClass *entity_parent_class = NULL;
67
 
 
68
 
guint
69
 
mg_canvas_entity_get_type (void)
70
 
{
71
 
        static GType type = 0;
72
 
 
73
 
        if (!type) {
74
 
                static const GTypeInfo info = {
75
 
                        sizeof (MgCanvasEntityClass),
76
 
                        (GBaseInitFunc) NULL,
77
 
                        (GBaseFinalizeFunc) NULL,
78
 
                        (GClassInitFunc) mg_canvas_entity_class_init,
79
 
                        NULL,
80
 
                        NULL,
81
 
                        sizeof (MgCanvasEntity),
82
 
                        0,
83
 
                        (GInstanceInitFunc) mg_canvas_entity_init
84
 
                };              
85
 
 
86
 
                type = g_type_register_static (MG_CANVAS_ITEM_TYPE, "MgCanvasEntity", &info, 0);
87
 
        }
88
 
 
89
 
        return type;
90
 
}
91
 
 
92
 
        
93
 
 
94
 
static void
95
 
mg_canvas_entity_class_init (MgCanvasEntityClass * class)
96
 
{
97
 
        GObjectClass   *object_class = G_OBJECT_CLASS (class);
98
 
 
99
 
        entity_parent_class = g_type_class_peek_parent (class);
100
 
 
101
 
        object_class->dispose = mg_canvas_entity_dispose;
102
 
        object_class->finalize = mg_canvas_entity_finalize;
103
 
 
104
 
        /* Properties */
105
 
        object_class->set_property = mg_canvas_entity_set_property;
106
 
        object_class->get_property = mg_canvas_entity_get_property;
107
 
 
108
 
        g_object_class_install_property
109
 
                (object_class, PROP_ENTITY,
110
 
                 g_param_spec_pointer ("entity", NULL, NULL, (G_PARAM_READABLE | G_PARAM_WRITABLE)));
111
 
        g_object_class_install_property 
112
 
                (object_class, PROP_SCALE,
113
 
                 g_param_spec_double ("scale", NULL, NULL, 0., G_MAXDOUBLE, 0., G_PARAM_WRITABLE));
114
 
}
115
 
 
116
 
static void
117
 
mg_canvas_entity_init (MgCanvasEntity * entity)
118
 
{
119
 
        entity->priv = g_new0 (MgCanvasEntityPrivate, 1);
120
 
        entity->priv->entity = NULL;
121
 
        entity->priv->field_ypos = NULL;
122
 
 
123
 
        entity->priv->x_text_space = 3.;
124
 
        entity->priv->y_text_space = 3.;
125
 
}
126
 
 
127
 
static void clean_items (MgCanvasEntity *ce);
128
 
static void create_items (MgCanvasEntity *ce);
129
 
static void entity_nullified_cb (MgEntity *ent, MgCanvasEntity *ce);
130
 
static void entity_changed_cb (MgEntity *ent, MgCanvasEntity *ce);
131
 
 
132
 
static void
133
 
mg_canvas_entity_dispose (GObject   * object)
134
 
{
135
 
        MgCanvasEntity *ce;
136
 
        g_return_if_fail (object != NULL);
137
 
        g_return_if_fail (IS_MG_CANVAS_ENTITY (object));
138
 
 
139
 
        ce = MG_CANVAS_ENTITY (object);
140
 
        clean_items (ce);
141
 
        if (ce->priv->entity) {
142
 
                g_signal_handlers_disconnect_by_func (G_OBJECT (ce->priv->entity),
143
 
                                                      G_CALLBACK (entity_nullified_cb), ce);
144
 
                g_signal_handlers_disconnect_by_func (G_OBJECT (ce->priv->entity),
145
 
                                                      G_CALLBACK (entity_changed_cb), ce);
146
 
                ce->priv->entity = NULL;
147
 
        }
148
 
 
149
 
        /* for the parent class */
150
 
        entity_parent_class->dispose (object);
151
 
}
152
 
 
153
 
 
154
 
static void
155
 
mg_canvas_entity_finalize (GObject   * object)
156
 
{
157
 
        MgCanvasEntity *ce;
158
 
        g_return_if_fail (object != NULL);
159
 
        g_return_if_fail (IS_MG_CANVAS_ENTITY (object));
160
 
 
161
 
        ce = MG_CANVAS_ENTITY (object);
162
 
        if (ce->priv) {
163
 
                if (ce->priv->field_items)
164
 
                        g_slist_free (ce->priv->field_items);
165
 
                if (ce->priv->field_ypos)
166
 
                        g_free (ce->priv->field_ypos);
167
 
 
168
 
                g_free (ce->priv);
169
 
                ce->priv = NULL;
170
 
        }
171
 
 
172
 
        /* for the parent class */
173
 
        entity_parent_class->finalize (object);
174
 
}
175
 
 
176
 
static void 
177
 
mg_canvas_entity_set_property    (GObject              *object,
178
 
                                  guint                 param_id,
179
 
                                  const GValue         *value,
180
 
                                  GParamSpec           *pspec)
181
 
{
182
 
        MgCanvasEntity *ce;
183
 
        gpointer ptr;
184
 
        gdouble scale;
185
 
        GSList *list;
186
 
        PangoFontDescription *font_desc, *font_copy;
187
 
 
188
 
        ce = MG_CANVAS_ENTITY (object);
189
 
 
190
 
        switch (param_id) {
191
 
        case PROP_ENTITY:
192
 
                ptr = g_value_get_pointer (value);
193
 
                if (ptr == ce->priv->entity)
194
 
                        return;
195
 
 
196
 
                if (ce->priv->entity) {
197
 
                        g_signal_handlers_disconnect_by_func (G_OBJECT (ce->priv->entity),
198
 
                                                              G_CALLBACK (entity_nullified_cb), ce);
199
 
                        g_signal_handlers_disconnect_by_func (G_OBJECT (ce->priv->entity),
200
 
                                                              G_CALLBACK (entity_changed_cb), ce);
201
 
                        ce->priv->entity = NULL;
202
 
                        clean_items (ce);
203
 
                }
204
 
                if (ptr) {
205
 
                        g_return_if_fail (IS_MG_ENTITY (ptr));
206
 
                        ce->priv->entity = ptr;
207
 
                        g_signal_connect (G_OBJECT (ce->priv->entity), "nullified",
208
 
                                          G_CALLBACK (entity_nullified_cb), ce);
209
 
                        /* Signals to keep the display up to date */
210
 
                        g_signal_connect (G_OBJECT (ce->priv->entity), "changed",
211
 
                                          G_CALLBACK (entity_changed_cb), ce);
212
 
 
213
 
                        create_items (ce);
214
 
                }
215
 
                break;
216
 
        case PROP_SCALE:
217
 
                scale = g_value_get_double (value);
218
 
                list = ce->priv->field_items;
219
 
                while (list) {
220
 
                        g_object_set (G_OBJECT (list->data), "scale", scale, NULL);
221
 
                        list = g_slist_next (list);
222
 
                }
223
 
                g_object_get (G_OBJECT (ce->priv->title), "font-desc", &font_desc, NULL);
224
 
                font_copy = pango_font_description_copy (font_desc);
225
 
                pango_font_description_set_size (font_copy, scale * ce->priv->init_font_size);
226
 
                g_object_set (G_OBJECT (ce->priv->title), "font-desc", font_copy, NULL);
227
 
                pango_font_description_free (font_copy);
228
 
        }
229
 
}
230
 
 
231
 
static void 
232
 
mg_canvas_entity_get_property    (GObject              *object,
233
 
                                    guint                 param_id,
234
 
                                    GValue               *value,
235
 
                                    GParamSpec           *pspec)
236
 
{
237
 
        TO_IMPLEMENT;
238
 
}
239
 
 
240
 
static void
241
 
entity_nullified_cb (MgEntity *ent, MgCanvasEntity *ce)
242
 
{
243
 
        gtk_object_destroy (GTK_OBJECT (ce));
244
 
}
245
 
 
246
 
static void
247
 
entity_changed_cb (MgEntity *ent, MgCanvasEntity *ce)
248
 
{
249
 
        create_items (ce);
250
 
}
251
 
 
252
 
/* 
253
 
 * destroy any existing GnomeCanvasItem obejcts 
254
 
 */
255
 
static void 
256
 
clean_items (MgCanvasEntity *ce)
257
 
{
258
 
        /* destroy all the items in the group */
259
 
        while (GNOME_CANVAS_GROUP (ce)->item_list) 
260
 
                gtk_object_destroy (GTK_OBJECT (GNOME_CANVAS_GROUP (ce)->item_list->data));
261
 
 
262
 
        ce->priv->title = NULL;
263
 
 
264
 
        /* free the fields positions */
265
 
        if (ce->priv->field_ypos) {
266
 
                g_free (ce->priv->field_ypos);
267
 
                ce->priv->field_ypos = NULL;
268
 
        }
269
 
}
270
 
 
271
 
static int button_item_event (GnomeCanvasItem *ci, GdkEvent *event, MgCanvasEntity *ce);
272
 
static void field_item_destroy_cb (MgCanvasField *field, MgCanvasEntity *ce);
273
 
 
274
 
/*
275
 
 * create new GnomeCanvasItem objects
276
 
 */
277
 
static void 
278
 
create_items (MgCanvasEntity *ce)
279
 
{
280
 
        GnomeCanvasItem *item;
281
 
        const gchar *cstr;
282
 
        double x1, y1, x2, y2;
283
 
        GSList *list, *tmplist;
284
 
        gdouble x, sqsize, radius;
285
 
        gdouble title_text_height, title_text_width, total_width;
286
 
        gint fieldn;
287
 
 
288
 
        /* WARNING: the text items (GNOME_TYPE_CANVAS_TEXT) are first drawn without taking care of the real zoom factor =>
289
 
         * we must take that into account when using the text sizes */
290
 
        gdouble scale = GNOME_CANVAS_ITEM (ce)->canvas->pixels_per_unit;
291
 
 
292
 
        clean_items (ce);
293
 
 
294
 
        /* Title of the Table or query */
295
 
        ce->priv->init_font_size = pango_font_description_get_size 
296
 
                (GTK_WIDGET (GNOME_CANVAS_ITEM (ce)->canvas)->style->font_desc);
297
 
        cstr = mg_base_get_name (MG_BASE (ce->priv->entity));
298
 
        item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (ce),
299
 
                                      GNOME_TYPE_CANVAS_TEXT,
300
 
                                      "font-desc", GTK_WIDGET (GNOME_CANVAS_ITEM (ce)->canvas)->style->font_desc,
301
 
                                      "weight", PANGO_WEIGHT_BOLD,
302
 
                                      "text", cstr,
303
 
                                      "x", ce->priv->x_text_space, 
304
 
                                      "y", ce->priv->y_text_space,
305
 
                                      "fill_color", "black",
306
 
                                      "justification", GTK_JUSTIFY_RIGHT, 
307
 
                                      "anchor", GTK_ANCHOR_NORTH_WEST, 
308
 
                                      NULL);
309
 
        gnome_canvas_item_get_bounds (item, &x1, &y1, &x2, &y2);
310
 
        ce->priv->title = item;
311
 
 
312
 
        /* Getting text metrics */
313
 
        title_text_height = (y2 - y1) * scale;
314
 
        title_text_width = (x2 - x1) * scale;
315
 
        total_width = title_text_width + 2 * ce->priv->x_text_space;
316
 
 
317
 
        /* fields */
318
 
        sqsize = title_text_height * 0.6;
319
 
        list = mg_entity_get_visible_fields (ce->priv->entity);
320
 
 
321
 
        ce->priv->field_ypos = g_new0 (gdouble, g_slist_length (list) + 1);
322
 
        ce->priv->field_ypos [0] = title_text_height + 3* ce->priv->y_text_space;
323
 
 
324
 
        tmplist = list;
325
 
        fieldn = 0;
326
 
        while (tmplist) {
327
 
                item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (ce),
328
 
                                              MG_CANVAS_FIELD_TYPE,
329
 
                                              "x", 0.,
330
 
                                              "y", ce->priv->field_ypos[fieldn],
331
 
                                              "field", tmplist->data,
332
 
                                              NULL);    
333
 
                ce->priv->field_items = g_slist_append (ce->priv->field_items, item);
334
 
                
335
 
                g_signal_connect (G_OBJECT (item), "destroy",
336
 
                                  G_CALLBACK (field_item_destroy_cb), ce);
337
 
 
338
 
                gnome_canvas_item_get_bounds (item, &x1, &y1, &x2, &y2);
339
 
                ce->priv->field_ypos[fieldn+1] = y2;
340
 
 
341
 
                if (x2 - x1 > total_width)
342
 
                        total_width = x2 - x1;
343
 
 
344
 
                tmplist = g_slist_next (tmplist);
345
 
                fieldn++;
346
 
        }
347
 
        g_slist_free (list);
348
 
 
349
 
        /* "button" to close the MgCanvasEntity  */
350
 
        sqsize = title_text_height * 0.8;
351
 
        x = total_width + ce->priv->x_text_space;
352
 
        if (x - sqsize - 2*ce->priv->x_text_space < title_text_width)
353
 
                x = title_text_width + sqsize + 2*ce->priv->x_text_space;
354
 
 
355
 
        item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (ce),
356
 
                                      GNOME_TYPE_CANVAS_RECT,
357
 
                                      "x1", x - sqsize,
358
 
                                      "y1", ce->priv->y_text_space,
359
 
                                      "x2", x,
360
 
                                      "y2", ce->priv->y_text_space + sqsize,
361
 
                                      "fill_color", "white",
362
 
                                      "outline_color", "black",
363
 
                                      "width_units", 1.0,
364
 
                                      NULL);
365
 
        gnome_canvas_item_raise_to_top (item);
366
 
        g_signal_connect (G_OBJECT (item),"event",
367
 
                          G_CALLBACK (button_item_event), ce);
368
 
 
369
 
        if (x - ce->priv->x_text_space > total_width)
370
 
                total_width = x - ce->priv->x_text_space;
371
 
        
372
 
        cstr = MG_CANVAS_ENTITY_COLOR;
373
 
        if (IS_MG_DB_TABLE (ce->priv->entity))
374
 
                cstr = MG_CANVAS_DB_TABLE_COLOR;
375
 
        if (IS_MG_QUERY (ce->priv->entity))
376
 
                cstr = MG_CANVAS_QUERY_COLOR;
377
 
 
378
 
        radius = sqsize * .2;
379
 
        item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (ce),
380
 
                                      GNOME_TYPE_CANVAS_ELLIPSE,
381
 
                                      "x1", x - sqsize/2. - radius,
382
 
                                      "y1", ce->priv->y_text_space + sqsize/2. - radius,
383
 
                                      "x2", x - sqsize/2. + radius,
384
 
                                      "y2", ce->priv->y_text_space + sqsize/2. + radius,
385
 
                                      "fill_color", cstr,
386
 
                                      "outline_color", "black",
387
 
                                      "width_units", 1.0,
388
 
                                      NULL);
389
 
        gnome_canvas_item_raise_to_top (item);
390
 
        g_signal_connect (G_OBJECT (item),"event",
391
 
                          G_CALLBACK (button_item_event), ce);
392
 
 
393
 
        /* Top little frame */
394
 
        item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (ce),
395
 
                                      GNOME_TYPE_CANVAS_RECT,
396
 
                                      "x1", (double) 0,
397
 
                                      "y1", (double) 0,
398
 
                                      "x2", total_width + 2. * ce->priv->x_text_space,
399
 
                                      "y2", title_text_height + 2 * ce->priv->y_text_space,
400
 
                                      "outline_color", "black",
401
 
                                      "fill_color", cstr, 
402
 
                                      "width_units", 1.0, 
403
 
                                      NULL);
404
 
        gnome_canvas_item_lower_to_bottom (item);
405
 
 
406
 
        /* Outline frame */
407
 
        item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (ce),
408
 
                                      GNOME_TYPE_CANVAS_RECT,
409
 
                                      "x1", (double) 0,
410
 
                                      "y1", (double) 0,
411
 
                                      "x2", total_width + 2. * ce->priv->x_text_space,
412
 
                                      "y2", ce->priv->field_ypos[fieldn] + 1,
413
 
                                      "outline_color", "black",
414
 
                                      "fill_color", "white",
415
 
                                      "width_units", 1.0, NULL);
416
 
        gnome_canvas_item_lower_to_bottom (item);
417
 
 
418
 
        total_width += 2. * ce->priv->x_text_space;
419
 
 
420
 
        /* setting the fields' background width to be the same for all */
421
 
        tmplist = ce->priv->field_items;
422
 
        while (tmplist) {
423
 
                g_object_set (G_OBJECT (tmplist->data), "width", total_width, NULL);
424
 
                tmplist = g_slist_next (tmplist);
425
 
        }
426
 
 
427
 
        /* make sure the scale is correctly applied to text items */
428
 
        g_object_set (G_OBJECT (ce), "scale", scale, NULL);
429
 
}
430
 
 
431
 
static void
432
 
field_item_destroy_cb (MgCanvasField *field, MgCanvasEntity *ce)
433
 
{
434
 
        g_assert (g_slist_find (ce->priv->field_items, field));
435
 
        ce->priv->field_items = g_slist_remove (ce->priv->field_items, field);
436
 
}
437
 
 
438
 
static void popup_delete_cb (GtkMenuItem *mitem, MgCanvasEntity *ce);
439
 
static int 
440
 
button_item_event (GnomeCanvasItem *ci, GdkEvent *event, MgCanvasEntity *ce)
441
 
{
442
 
        gboolean done = TRUE;
443
 
        GtkWidget *menu, *entry;
444
 
 
445
 
        switch (event->type) {
446
 
        case GDK_BUTTON_PRESS:
447
 
                menu = gtk_menu_new ();
448
 
                entry = gtk_menu_item_new_with_label (_("Remove"));
449
 
                g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (popup_delete_cb), ce);
450
 
                gtk_menu_append (GTK_MENU (menu), entry);
451
 
                gtk_widget_show (entry);
452
 
                gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
453
 
                                NULL, NULL, ((GdkEventButton *)event)->button,
454
 
                                ((GdkEventButton *)event)->time);
455
 
                done = FALSE;
456
 
                break;
457
 
        default:
458
 
                done = FALSE;
459
 
                break;
460
 
        }
461
 
 
462
 
        return done;    
463
 
}
464
 
 
465
 
static void
466
 
popup_delete_cb (GtkMenuItem *mitem, MgCanvasEntity *ce)
467
 
{
468
 
        MgGraphItem *gitem;
469
 
 
470
 
        gitem = mg_canvas_item_get_graph_item (MG_CANVAS_ITEM (ce));
471
 
        mg_base_nullify (MG_BASE (gitem));
472
 
}
473
 
 
474
 
/**
475
 
 * mg_canvas_entity_get_field_item
476
 
 * @ce: a #MgCanvasEntity object
477
 
 * @field: a #MgField object
478
 
 *
479
 
 * Get the #MgCanvasField object representing @field
480
 
 * in @ce.
481
 
 *
482
 
 * Returns: the corresponding #MgCanvasField
483
 
 */
484
 
MgCanvasField *
485
 
mg_canvas_entity_get_field_item (MgCanvasEntity *ce, MgField *field)
486
 
{
487
 
        GSList *fields;
488
 
        gint pos;
489
 
 
490
 
        g_return_val_if_fail (ce && IS_MG_CANVAS_ENTITY (ce), NULL);
491
 
        g_return_val_if_fail (ce->priv, NULL);
492
 
        g_return_val_if_fail (ce->priv->entity, NULL);
493
 
 
494
 
        fields = mg_entity_get_visible_fields (ce->priv->entity);
495
 
        pos = g_slist_index (fields, field);
496
 
        g_return_val_if_fail (pos >= 0, NULL);
497
 
 
498
 
        return g_slist_nth_data (ce->priv->field_items, pos);
499
 
}
500
 
 
501
 
 
502
 
/**
503
 
 * mg_canvas_entity_get_field_ypos
504
 
 * @ce: a #MgCanvasEntity object
505
 
 * @field: a #MgField object
506
 
 *
507
 
 * Get the Y position of the #MgCanvasField object representing @field
508
 
 * in @ce, in @ce's coordinates.
509
 
 *
510
 
 * Returns: the Y coordinate.
511
 
 */
512
 
gdouble
513
 
mg_canvas_entity_get_field_ypos (MgCanvasEntity *ce, MgField *field)
514
 
{
515
 
        gint pos;
516
 
 
517
 
        g_return_val_if_fail (ce && IS_MG_CANVAS_ENTITY (ce), 0.);
518
 
        g_return_val_if_fail (ce->priv, 0.);
519
 
        g_return_val_if_fail (ce->priv->entity, 0.);
520
 
        g_return_val_if_fail (ce->priv->field_ypos, 0.);
521
 
 
522
 
        pos = mg_entity_get_field_index (ce->priv->entity, field);
523
 
        g_return_val_if_fail (pos >= 0, 0.);
524
 
        return (ce->priv->field_ypos[pos+1] + ce->priv->field_ypos[pos]) / 2.;
525
 
}