~ml-launchpad/ubuntu/natty/gcompris/fix-for-777349

« back to all changes in this revision

Viewing changes to src/goocanvas/src/goocanvasitemsimple.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Gariepy, Marc Gariepy, Stephane Graber
  • Date: 2010-01-04 17:42:49 UTC
  • mfrom: (1.1.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20100104174249-7bupatd9dtxyhvs4
Tags: 9.0-0ubuntu1
[Marc Gariepy]
* New upstream release (9.0).
* Remove cache.c from POTFILES to avoid FTBFS
* Remove unneeded rm in debian/rules (file no longer exists upstream)

[Stephane Graber]
* Bump Debian standards to 3.8.3
* Add patch system (dpatch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * GooCanvas. Copyright (C) 2005-6 Damon Chaplin.
 
3
 * Released under the GNU LGPL license. See COPYING for details.
 
4
 *
 
5
 * goocanvasitemsimple.c - abstract base class for canvas items.
 
6
 */
 
7
 
 
8
/**
 
9
 * SECTION:goocanvasitemsimple
 
10
 * @Title: GooCanvasItemSimple
 
11
 * @Short_Description: the base class for the standard canvas items.
 
12
 * @Stability_Level: 
 
13
 * @See_Also: 
 
14
 *
 
15
 * #GooCanvasItemSimple is used as a base class for all of the standard canvas
 
16
 * items. It can also be used as the base class for new custom canvas items.
 
17
 *
 
18
 * It provides default implementations for many of the #GooCanvasItem
 
19
 * methods.
 
20
 *
 
21
 * For very simple items, all that is needed is to implement the create_path()
 
22
 * method. (#GooCanvasEllipse, #GooCanvasRect and #GooCanvasPath do this.)
 
23
 *
 
24
 * More complicated items need to implement the update(), paint() and
 
25
 * is_item_at() methods instead. (#GooCanvasImage, #GooCanvasPolyline,
 
26
 * #GooCanvasText and #GooCanvasWidget do this.) They may also need to
 
27
 * override some of the other GooCanvasItem methods such as set_canvas(),
 
28
 * set_parent() or allocate_area() if special code is needed. (#GooCanvasWidget
 
29
 * does this to make sure the #GtkWidget is embedded in the #GooCanvas widget
 
30
 * correctly.)
 
31
 */
 
32
#include <config.h>
 
33
#include <glib/gi18n-lib.h>
 
34
#include <gtk/gtk.h>
 
35
#include "goocanvasprivate.h"
 
36
#include "goocanvasitemsimple.h"
 
37
#include "goocanvas.h"
 
38
#include "goocanvasatk.h"
 
39
 
 
40
 
 
41
enum {
 
42
  PROP_0,
 
43
 
 
44
  /* Basic drawing properties. */
 
45
  PROP_STROKE_PATTERN,
 
46
  PROP_FILL_PATTERN,
 
47
  PROP_FILL_RULE,
 
48
  PROP_OPERATOR,
 
49
  PROP_ANTIALIAS,
 
50
 
 
51
  /* Line style & width properties. */
 
52
  PROP_LINE_WIDTH,
 
53
  PROP_LINE_CAP,
 
54
  PROP_LINE_JOIN,
 
55
  PROP_LINE_JOIN_MITER_LIMIT,
 
56
  PROP_LINE_DASH,
 
57
 
 
58
  /* Font properties. */
 
59
  PROP_FONT,
 
60
  PROP_FONT_DESC,
 
61
  PROP_HINT_METRICS,
 
62
 
 
63
  /* Convenience properties. */
 
64
  PROP_STROKE_COLOR,
 
65
  PROP_STROKE_COLOR_RGBA,
 
66
  PROP_STROKE_PIXBUF,
 
67
  PROP_FILL_COLOR,
 
68
  PROP_FILL_COLOR_RGBA,
 
69
  PROP_FILL_PIXBUF,
 
70
 
 
71
  /* Other properties. Note that the order here is important PROP_TRANSFORM
 
72
     must be the first non-style property. see set_property(). */
 
73
  PROP_TRANSFORM,
 
74
  PROP_PARENT,
 
75
  PROP_VISIBILITY,
 
76
  PROP_VISIBILITY_THRESHOLD,
 
77
  PROP_POINTER_EVENTS,
 
78
  PROP_TITLE,
 
79
  PROP_DESCRIPTION,
 
80
  PROP_CAN_FOCUS,
 
81
  PROP_CLIP_PATH,
 
82
  PROP_CLIP_FILL_RULE,
 
83
  PROP_TOOLTIP
 
84
};
 
85
 
 
86
static gboolean accessibility_enabled = FALSE;
 
87
 
 
88
static void canvas_item_interface_init          (GooCanvasItemIface   *iface);
 
89
static void goo_canvas_item_simple_dispose      (GObject              *object);
 
90
static void goo_canvas_item_simple_finalize     (GObject              *object);
 
91
static void goo_canvas_item_simple_get_property (GObject              *object,
 
92
                                                 guint                 prop_id,
 
93
                                                 GValue               *value,
 
94
                                                 GParamSpec           *pspec);
 
95
static void goo_canvas_item_simple_set_property (GObject              *object,
 
96
                                                 guint                 prop_id,
 
97
                                                 const GValue         *value,
 
98
                                                 GParamSpec           *pspec);
 
99
 
 
100
static void     goo_canvas_item_simple_default_create_path (GooCanvasItemSimple   *simple,
 
101
                                                            cairo_t               *cr);
 
102
static void     goo_canvas_item_simple_default_update      (GooCanvasItemSimple   *simple,
 
103
                                                            cairo_t               *cr);
 
104
static void     goo_canvas_item_simple_default_paint       (GooCanvasItemSimple   *simple,
 
105
                                                            cairo_t               *cr,
 
106
                                                            const GooCanvasBounds *bounds);
 
107
static gboolean goo_canvas_item_simple_default_is_item_at  (GooCanvasItemSimple   *simple,
 
108
                                                            double                 x,
 
109
                                                            double                 y,
 
110
                                                            cairo_t               *cr,
 
111
                                                            gboolean               is_pointer_event);
 
112
 
 
113
 
 
114
G_DEFINE_TYPE_WITH_CODE (GooCanvasItemSimple, goo_canvas_item_simple,
 
115
                         G_TYPE_OBJECT,
 
116
                         G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
 
117
                                                canvas_item_interface_init))
 
118
 
 
119
 
 
120
static void
 
121
goo_canvas_item_simple_install_common_properties (GObjectClass *gobject_class)
 
122
{
 
123
  /* Basic drawing properties. */
 
124
  g_object_class_install_property (gobject_class, PROP_STROKE_PATTERN,
 
125
                                   g_param_spec_boxed ("stroke-pattern",
 
126
                                                       _("Stroke Pattern"),
 
127
                                                       _("The pattern to use to paint the perimeter of the item, or NULL disable painting"),
 
128
                                                       GOO_TYPE_CAIRO_PATTERN,
 
129
                                                       G_PARAM_READWRITE));
 
130
 
 
131
  g_object_class_install_property (gobject_class, PROP_FILL_PATTERN,
 
132
                                   g_param_spec_boxed ("fill-pattern",
 
133
                                                       _("Fill Pattern"),
 
134
                                                       _("The pattern to use to paint the interior of the item, or NULL to disable painting"),
 
135
                                                       GOO_TYPE_CAIRO_PATTERN,
 
136
                                                       G_PARAM_READWRITE));
 
137
 
 
138
  g_object_class_install_property (gobject_class, PROP_FILL_RULE,
 
139
                                   g_param_spec_enum ("fill-rule",
 
140
                                                      _("Fill Rule"),
 
141
                                                      _("The fill rule used to determine which parts of the item are filled"),
 
142
                                                      GOO_TYPE_CAIRO_FILL_RULE,
 
143
                                                      CAIRO_FILL_RULE_WINDING,
 
144
                                                      G_PARAM_READWRITE));
 
145
 
 
146
  g_object_class_install_property (gobject_class, PROP_OPERATOR,
 
147
                                   g_param_spec_enum ("operator",
 
148
                                                      _("Operator"),
 
149
                                                      _("The compositing operator to use"),
 
150
                                                      GOO_TYPE_CAIRO_OPERATOR,
 
151
                                                      CAIRO_OPERATOR_OVER,
 
152
                                                      G_PARAM_READWRITE));
 
153
 
 
154
  g_object_class_install_property (gobject_class, PROP_ANTIALIAS,
 
155
                                   g_param_spec_enum ("antialias",
 
156
                                                      _("Antialias"),
 
157
                                                      _("The antialiasing mode to use"),
 
158
                                                      GOO_TYPE_CAIRO_ANTIALIAS,
 
159
                                                      CAIRO_ANTIALIAS_GRAY,
 
160
                                                      G_PARAM_READWRITE));
 
161
 
 
162
  /* Line style & width properties. */
 
163
  g_object_class_install_property (gobject_class, PROP_LINE_WIDTH,
 
164
                                   g_param_spec_double ("line-width",
 
165
                                                        _("Line Width"),
 
166
                                                        _("The line width to use for the item's perimeter"),
 
167
                                                        0.0, G_MAXDOUBLE, 2.0,
 
168
                                                        G_PARAM_READWRITE));
 
169
 
 
170
  g_object_class_install_property (gobject_class, PROP_LINE_CAP,
 
171
                                   g_param_spec_enum ("line-cap",
 
172
                                                      _("Line Cap"),
 
173
                                                      _("The line cap style to use"),
 
174
                                                      GOO_TYPE_CAIRO_LINE_CAP,
 
175
                                                      CAIRO_LINE_CAP_BUTT,
 
176
                                                      G_PARAM_READWRITE));
 
177
 
 
178
  g_object_class_install_property (gobject_class, PROP_LINE_JOIN,
 
179
                                   g_param_spec_enum ("line-join",
 
180
                                                      _("Line Join"),
 
181
                                                      _("The line join style to use"),
 
182
                                                      GOO_TYPE_CAIRO_LINE_JOIN,
 
183
                                                      CAIRO_LINE_JOIN_MITER,
 
184
                                                      G_PARAM_READWRITE));
 
185
 
 
186
  g_object_class_install_property (gobject_class, PROP_LINE_JOIN_MITER_LIMIT,
 
187
                                   g_param_spec_double ("line-join-miter-limit",
 
188
                                                        _("Miter Limit"),
 
189
                                                        _("The smallest angle to use with miter joins, in degrees. Bevel joins will be used below this limit"),
 
190
                                                        0.0, G_MAXDOUBLE, 10.0,
 
191
                                                        G_PARAM_READWRITE));
 
192
 
 
193
  g_object_class_install_property (gobject_class, PROP_LINE_DASH,
 
194
                                   g_param_spec_boxed ("line-dash",
 
195
                                                       _("Line Dash"),
 
196
                                                       _("The dash pattern to use"),
 
197
                                                       GOO_TYPE_CANVAS_LINE_DASH,
 
198
                                                       G_PARAM_READWRITE));
 
199
 
 
200
  /* Font properties. */
 
201
  g_object_class_install_property (gobject_class, PROP_FONT,
 
202
                                   g_param_spec_string ("font",
 
203
                                                        _("Font"),
 
204
                                                        _("The base font to use for the text"),
 
205
                                                        NULL,
 
206
                                                        G_PARAM_READWRITE));
 
207
 
 
208
  g_object_class_install_property (gobject_class, PROP_FONT_DESC,
 
209
                                   g_param_spec_boxed ("font-desc",
 
210
                                                       _("Font Description"),
 
211
                                                       _("The attributes specifying which font to use"),
 
212
                                                       PANGO_TYPE_FONT_DESCRIPTION,
 
213
                                                       G_PARAM_READWRITE));
 
214
 
 
215
  g_object_class_install_property (gobject_class, PROP_HINT_METRICS,
 
216
                                   g_param_spec_enum ("hint-metrics",
 
217
                                                      _("Hint Metrics"),
 
218
                                                      _("The hinting to be used for font metrics"),
 
219
                                                      GOO_TYPE_CAIRO_HINT_METRICS,
 
220
                                                      CAIRO_HINT_METRICS_OFF,
 
221
                                                      G_PARAM_READWRITE));
 
222
 
 
223
  /* Convenience properties - writable only. */
 
224
  g_object_class_install_property (gobject_class, PROP_STROKE_COLOR,
 
225
                                   g_param_spec_string ("stroke-color",
 
226
                                                        _("Stroke Color"),
 
227
                                                        _("The color to use for the item's perimeter. To disable painting set the 'stroke-pattern' property to NULL"),
 
228
                                                        NULL,
 
229
                                                        G_PARAM_WRITABLE));
 
230
 
 
231
  g_object_class_install_property (gobject_class, PROP_STROKE_COLOR_RGBA,
 
232
                                   g_param_spec_uint ("stroke-color-rgba",
 
233
                                                      _("Stroke Color RGBA"),
 
234
                                                      _("The color to use for the item's perimeter, specified as a 32-bit integer value. To disable painting set the 'stroke-pattern' property to NULL"),
 
235
                                                      0, G_MAXUINT, 0,
 
236
                                                      G_PARAM_READWRITE));
 
237
 
 
238
  g_object_class_install_property (gobject_class, PROP_STROKE_PIXBUF,
 
239
                                   g_param_spec_object ("stroke-pixbuf",
 
240
                                                        _("Stroke Pixbuf"),
 
241
                                                        _("The pixbuf to use to draw the item's perimeter. To disable painting set the 'stroke-pattern' property to NULL"),
 
242
                                                        GDK_TYPE_PIXBUF,
 
243
                                                        G_PARAM_WRITABLE));
 
244
 
 
245
  g_object_class_install_property (gobject_class, PROP_FILL_COLOR,
 
246
                                   g_param_spec_string ("fill-color",
 
247
                                                        _("Fill Color"),
 
248
                                                        _("The color to use to paint the interior of the item. To disable painting set the 'fill-pattern' property to NULL"),
 
249
                                                        NULL,
 
250
                                                        G_PARAM_WRITABLE));
 
251
 
 
252
  g_object_class_install_property (gobject_class, PROP_FILL_COLOR_RGBA,
 
253
                                   g_param_spec_uint ("fill-color-rgba",
 
254
                                                      _("Fill Color RGBA"),
 
255
                                                      _("The color to use to paint the interior of the item, specified as a 32-bit integer value. To disable painting set the 'fill-pattern' property to NULL"),
 
256
                                                      0, G_MAXUINT, 0,
 
257
                                                      G_PARAM_READWRITE));
 
258
 
 
259
  g_object_class_install_property (gobject_class, PROP_FILL_PIXBUF,
 
260
                                   g_param_spec_object ("fill-pixbuf",
 
261
                                                        _("Fill Pixbuf"),
 
262
                                                        _("The pixbuf to use to paint the interior of the item. To disable painting set the 'fill-pattern' property to NULL"),
 
263
                                                        GDK_TYPE_PIXBUF,
 
264
                                                        G_PARAM_WRITABLE));
 
265
 
 
266
  /* Other properties. */
 
267
  g_object_class_override_property (gobject_class, PROP_PARENT,
 
268
                                    "parent");
 
269
 
 
270
  g_object_class_override_property (gobject_class, PROP_VISIBILITY,
 
271
                                    "visibility");
 
272
 
 
273
  g_object_class_override_property (gobject_class, PROP_VISIBILITY_THRESHOLD,
 
274
                                    "visibility-threshold");
 
275
 
 
276
  g_object_class_override_property (gobject_class, PROP_TRANSFORM,
 
277
                                    "transform");
 
278
 
 
279
  g_object_class_override_property (gobject_class, PROP_POINTER_EVENTS,
 
280
                                    "pointer-events");
 
281
 
 
282
  g_object_class_override_property (gobject_class, PROP_TITLE,
 
283
                                    "title");
 
284
 
 
285
  g_object_class_override_property (gobject_class, PROP_DESCRIPTION,
 
286
                                    "description");
 
287
 
 
288
  g_object_class_override_property (gobject_class, PROP_CAN_FOCUS,
 
289
                                    "can-focus");
 
290
 
 
291
  g_object_class_override_property (gobject_class, PROP_TOOLTIP,
 
292
                                    "tooltip");
 
293
 
 
294
  /**
 
295
   * GooCanvasItemSimple:clip-path
 
296
   *
 
297
   * The sequence of commands describing the clip path of the item, specified
 
298
   * as a string using the same syntax
 
299
   * as in the <ulink url="http://www.w3.org/Graphics/SVG/">Scalable Vector
 
300
   * Graphics (SVG)</ulink> path element.
 
301
   */
 
302
  /**
 
303
   * GooCanvasItemModelSimple:clip-path
 
304
   *
 
305
   * The sequence of commands describing the clip path of the item, specified
 
306
   * as a string using the same syntax
 
307
   * as in the <ulink url="http://www.w3.org/Graphics/SVG/">Scalable Vector
 
308
   * Graphics (SVG)</ulink> path element.
 
309
   */
 
310
  g_object_class_install_property (gobject_class, PROP_CLIP_PATH,
 
311
                                   g_param_spec_string ("clip-path",
 
312
                                                        _("Clip Path"),
 
313
                                                        _("The sequence of path commands specifying the clip path"),
 
314
                                                        NULL,
 
315
                                                        G_PARAM_WRITABLE));
 
316
 
 
317
  g_object_class_install_property (gobject_class, PROP_CLIP_FILL_RULE,
 
318
                                   g_param_spec_enum ("clip-fill-rule",
 
319
                                                      _("Clip Fill Rule"),
 
320
                                                      _("The fill rule used to determine which parts of the item are clipped"),
 
321
                                                      GOO_TYPE_CAIRO_FILL_RULE,
 
322
                                                      CAIRO_FILL_RULE_WINDING,
 
323
                                                      G_PARAM_READWRITE));
 
324
 
 
325
}
 
326
 
 
327
 
 
328
static void
 
329
goo_canvas_item_simple_class_init (GooCanvasItemSimpleClass *klass)
 
330
{
 
331
  GObjectClass *gobject_class = (GObjectClass*) klass;
 
332
 
 
333
  gobject_class->dispose  = goo_canvas_item_simple_dispose;
 
334
  gobject_class->finalize = goo_canvas_item_simple_finalize;
 
335
 
 
336
  gobject_class->get_property = goo_canvas_item_simple_get_property;
 
337
  gobject_class->set_property = goo_canvas_item_simple_set_property;
 
338
 
 
339
  /* Register our accessible factory, but only if accessibility is enabled. */
 
340
  if (!ATK_IS_NO_OP_OBJECT_FACTORY (atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET)))
 
341
    {
 
342
      accessibility_enabled = TRUE;
 
343
      atk_registry_set_factory_type (atk_get_default_registry (),
 
344
                                     GOO_TYPE_CANVAS_ITEM_SIMPLE,
 
345
                                     goo_canvas_item_accessible_factory_get_type ());
 
346
    }
 
347
 
 
348
  goo_canvas_item_simple_install_common_properties (gobject_class);
 
349
 
 
350
  klass->simple_create_path = goo_canvas_item_simple_default_create_path;
 
351
  klass->simple_update      = goo_canvas_item_simple_default_update;
 
352
  klass->simple_paint       = goo_canvas_item_simple_default_paint;
 
353
  klass->simple_is_item_at  = goo_canvas_item_simple_default_is_item_at;
 
354
}
 
355
 
 
356
 
 
357
static void
 
358
goo_canvas_item_simple_init (GooCanvasItemSimple *item)
 
359
{
 
360
  GooCanvasBounds *bounds = &item->bounds;
 
361
 
 
362
  bounds->x1 = bounds->y1 = bounds->x2 = bounds->y2 = 0.0;
 
363
  item->simple_data = g_slice_new0 (GooCanvasItemSimpleData);
 
364
  item->simple_data->visibility = GOO_CANVAS_ITEM_VISIBLE;
 
365
  item->simple_data->pointer_events = GOO_CANVAS_EVENTS_VISIBLE_PAINTED;
 
366
  item->simple_data->clip_fill_rule = CAIRO_FILL_RULE_WINDING;
 
367
  item->need_update = TRUE;
 
368
  item->need_entire_subtree_update = TRUE;
 
369
}
 
370
 
 
371
 
 
372
static void
 
373
goo_canvas_item_simple_reset_model (GooCanvasItemSimple *simple)
 
374
{
 
375
  if (simple->model)
 
376
    {
 
377
      g_signal_handlers_disconnect_matched (simple->model, G_SIGNAL_MATCH_DATA,
 
378
                                            0, 0, NULL, NULL, simple);
 
379
      g_object_unref (simple->model);
 
380
      simple->model = NULL;
 
381
      simple->simple_data = NULL;
 
382
    }
 
383
}
 
384
 
 
385
 
 
386
/* Frees the contents of the GooCanvasItemSimpleData, but not the struct. */
 
387
static void
 
388
goo_canvas_item_simple_free_data (GooCanvasItemSimpleData *simple_data)
 
389
{
 
390
  if (simple_data)
 
391
    {
 
392
      if (simple_data->style)
 
393
        {
 
394
          g_object_unref (simple_data->style);
 
395
          simple_data->style = NULL;
 
396
        }
 
397
 
 
398
      if (simple_data->clip_path_commands)
 
399
        {
 
400
          g_array_free (simple_data->clip_path_commands, TRUE);
 
401
          simple_data->clip_path_commands = NULL;
 
402
        }
 
403
 
 
404
      g_slice_free (cairo_matrix_t, simple_data->transform);
 
405
      simple_data->transform = NULL;
 
406
    }
 
407
}
 
408
 
 
409
 
 
410
static void
 
411
goo_canvas_item_simple_dispose (GObject *object)
 
412
{
 
413
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
 
414
 
 
415
  /* Remove the view from the GooCanvas hash table. */
 
416
  if (simple->canvas && simple->model)
 
417
    goo_canvas_unregister_item (simple->canvas,
 
418
                                (GooCanvasItemModel*) simple->model);
 
419
 
 
420
  goo_canvas_item_simple_reset_model (simple);
 
421
  goo_canvas_item_simple_free_data (simple->simple_data);
 
422
 
 
423
  G_OBJECT_CLASS (goo_canvas_item_simple_parent_class)->dispose (object);
 
424
}
 
425
 
 
426
 
 
427
static void
 
428
goo_canvas_item_simple_finalize (GObject *object)
 
429
{
 
430
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
 
431
 
 
432
  g_slice_free (GooCanvasItemSimpleData, simple->simple_data);
 
433
  simple->simple_data = NULL;
 
434
 
 
435
  G_OBJECT_CLASS (goo_canvas_item_simple_parent_class)->finalize (object);
 
436
}
 
437
 
 
438
 
 
439
static void
 
440
goo_canvas_item_simple_get_common_property (GObject                 *object,
 
441
                                            GooCanvasItemSimpleData *simple_data,
 
442
                                            GooCanvas               *canvas,
 
443
                                            guint                    prop_id,
 
444
                                            GValue                  *value,
 
445
                                            GParamSpec              *pspec)
 
446
{
 
447
  GooCanvasStyle *style = simple_data->style;
 
448
  GValue *svalue;
 
449
  gdouble line_width = 2.0;
 
450
  gchar *font = NULL;
 
451
 
 
452
  switch (prop_id)
 
453
    {
 
454
      /* Basic drawing properties. */
 
455
    case PROP_STROKE_PATTERN:
 
456
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_stroke_pattern_id);
 
457
      g_value_set_boxed (value, svalue ? svalue->data[0].v_pointer : NULL);
 
458
      break;
 
459
    case PROP_FILL_PATTERN:
 
460
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_fill_pattern_id);
 
461
      g_value_set_boxed (value, svalue ? svalue->data[0].v_pointer : NULL);
 
462
      break;
 
463
    case PROP_FILL_RULE:
 
464
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_fill_rule_id);
 
465
      g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_FILL_RULE_WINDING);
 
466
      break;
 
467
    case PROP_OPERATOR:
 
468
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_operator_id);
 
469
      g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_OPERATOR_OVER);
 
470
      break;
 
471
    case PROP_ANTIALIAS:
 
472
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_antialias_id);
 
473
      g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_ANTIALIAS_GRAY);
 
474
      break;
 
475
 
 
476
      /* Line style & width properties. */
 
477
    case PROP_LINE_WIDTH:
 
478
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_width_id);
 
479
      if (svalue)
 
480
        line_width = svalue->data[0].v_double;
 
481
      else if (canvas)
 
482
        line_width = goo_canvas_get_default_line_width (canvas);
 
483
      g_value_set_double (value, line_width);
 
484
      break;
 
485
    case PROP_LINE_CAP:
 
486
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_cap_id);
 
487
      g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_LINE_CAP_BUTT);
 
488
      break;
 
489
    case PROP_LINE_JOIN:
 
490
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_join_id);
 
491
      g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_LINE_JOIN_MITER);
 
492
      break;
 
493
    case PROP_LINE_JOIN_MITER_LIMIT:
 
494
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_join_miter_limit_id);
 
495
      g_value_set_double (value, svalue ? svalue->data[0].v_double : 10.0);
 
496
      break;
 
497
    case PROP_LINE_DASH:
 
498
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_dash_id);
 
499
      g_value_set_boxed (value, svalue ? svalue->data[0].v_pointer : NULL);
 
500
      break;
 
501
 
 
502
      /* Font properties. */
 
503
    case PROP_FONT:
 
504
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_font_desc_id);
 
505
      if (svalue)
 
506
        font = pango_font_description_to_string (svalue->data[0].v_pointer);
 
507
      g_value_set_string (value, font);
 
508
      g_free (font);
 
509
      break;
 
510
    case PROP_FONT_DESC:
 
511
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_font_desc_id);
 
512
      g_value_set_boxed (value, svalue ? svalue->data[0].v_pointer : NULL);
 
513
      break;
 
514
    case PROP_HINT_METRICS:
 
515
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_hint_metrics_id);
 
516
      g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_HINT_METRICS_OFF);
 
517
      break;
 
518
 
 
519
      /* Convenience properties. */
 
520
    case PROP_STROKE_COLOR_RGBA:
 
521
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_stroke_pattern_id);
 
522
      if (svalue)
 
523
        goo_canvas_get_rgba_value_from_pattern (svalue->data[0].v_pointer,
 
524
                                                value);
 
525
      break;
 
526
    case PROP_FILL_COLOR_RGBA:
 
527
      svalue = goo_canvas_style_get_property (style, goo_canvas_style_fill_pattern_id);
 
528
      if (svalue)
 
529
        goo_canvas_get_rgba_value_from_pattern (svalue->data[0].v_pointer,
 
530
                                                value);
 
531
      break;
 
532
 
 
533
      /* Other properties. */
 
534
    case PROP_TRANSFORM:
 
535
      g_value_set_boxed (value, simple_data->transform);
 
536
      break;
 
537
    case PROP_VISIBILITY:
 
538
      g_value_set_enum (value, simple_data->visibility);
 
539
      break;
 
540
    case PROP_VISIBILITY_THRESHOLD:
 
541
      g_value_set_double (value, simple_data->visibility_threshold);
 
542
      break;
 
543
    case PROP_POINTER_EVENTS:
 
544
      g_value_set_flags (value, simple_data->pointer_events);
 
545
      break;
 
546
    case PROP_CAN_FOCUS:
 
547
      g_value_set_boolean (value, simple_data->can_focus);
 
548
      break;
 
549
    case PROP_CLIP_FILL_RULE:
 
550
      g_value_set_enum (value, simple_data->clip_fill_rule);
 
551
      break;
 
552
    case PROP_TOOLTIP:
 
553
      g_value_set_string (value, simple_data->tooltip);
 
554
      break;
 
555
    default:
 
556
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
557
      break;
 
558
    }
 
559
}
 
560
 
 
561
 
 
562
static void
 
563
goo_canvas_item_simple_get_property (GObject              *object,
 
564
                                     guint                 prop_id,
 
565
                                     GValue               *value,
 
566
                                     GParamSpec           *pspec)
 
567
{
 
568
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
 
569
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
570
  AtkObject *accessible;
 
571
 
 
572
  switch (prop_id)
 
573
    {
 
574
    case PROP_PARENT:
 
575
      g_value_set_object (value, simple->parent);
 
576
      break;
 
577
    case PROP_TITLE:
 
578
      accessible = atk_gobject_accessible_for_object (object);
 
579
      g_value_set_string (value, atk_object_get_name (accessible));
 
580
      break;
 
581
    case PROP_DESCRIPTION:
 
582
      accessible = atk_gobject_accessible_for_object (object);
 
583
      g_value_set_string (value, atk_object_get_description (accessible));
 
584
      break;
 
585
    default:
 
586
      goo_canvas_item_simple_get_common_property (object, simple_data,
 
587
                                                  simple->canvas, prop_id,
 
588
                                                  value, pspec);
 
589
      break;
 
590
    }
 
591
}
 
592
 
 
593
 
 
594
static gboolean
 
595
goo_canvas_item_simple_set_common_property (GObject                 *object,
 
596
                                            GooCanvasItemSimpleData *simple_data,
 
597
                                            guint                    prop_id,
 
598
                                            const GValue            *value,
 
599
                                            GParamSpec              *pspec)
 
600
{
 
601
  GooCanvasStyle *style;
 
602
  cairo_pattern_t *pattern;
 
603
  gboolean recompute_bounds = FALSE;
 
604
  cairo_matrix_t *transform;
 
605
  GValue tmpval = { 0 };
 
606
  const char *font_name;
 
607
  PangoFontDescription *font_desc = NULL;
 
608
 
 
609
  /* See if we need to create our own style. */
 
610
  if (prop_id < PROP_TRANSFORM)
 
611
    {
 
612
      if (!simple_data->style)
 
613
        {
 
614
          simple_data->style = goo_canvas_style_new ();
 
615
        }
 
616
      else if (!simple_data->own_style)
 
617
        {
 
618
          g_object_unref (simple_data->style);
 
619
          simple_data->style = goo_canvas_style_new ();
 
620
        }
 
621
      simple_data->own_style = TRUE;
 
622
    }
 
623
 
 
624
  style = simple_data->style;
 
625
 
 
626
  switch (prop_id)
 
627
    {
 
628
      /* Basic drawing properties. */
 
629
    case PROP_STROKE_PATTERN:
 
630
      goo_canvas_style_set_property (style, goo_canvas_style_stroke_pattern_id, value);
 
631
      break;
 
632
    case PROP_FILL_PATTERN:
 
633
      goo_canvas_style_set_property (style, goo_canvas_style_fill_pattern_id, value);
 
634
      break;
 
635
    case PROP_FILL_RULE:
 
636
      goo_canvas_style_set_property (style, goo_canvas_style_fill_rule_id, value);
 
637
      break;
 
638
    case PROP_OPERATOR:
 
639
      goo_canvas_style_set_property (style, goo_canvas_style_operator_id, value);
 
640
      break;
 
641
    case PROP_ANTIALIAS:
 
642
      goo_canvas_style_set_property (style, goo_canvas_style_antialias_id, value);
 
643
      break;
 
644
 
 
645
      /* Line style & width properties. */
 
646
    case PROP_LINE_WIDTH:
 
647
      goo_canvas_style_set_property (style, goo_canvas_style_line_width_id, value);
 
648
      recompute_bounds = TRUE;
 
649
      break;
 
650
    case PROP_LINE_CAP:
 
651
      goo_canvas_style_set_property (style, goo_canvas_style_line_cap_id, value);
 
652
      recompute_bounds = TRUE;
 
653
      break;
 
654
    case PROP_LINE_JOIN:
 
655
      goo_canvas_style_set_property (style, goo_canvas_style_line_join_id, value);
 
656
      recompute_bounds = TRUE;
 
657
      break;
 
658
    case PROP_LINE_JOIN_MITER_LIMIT:
 
659
      goo_canvas_style_set_property (style, goo_canvas_style_line_join_miter_limit_id,
 
660
                                     value);
 
661
      recompute_bounds = TRUE;
 
662
      break;
 
663
    case PROP_LINE_DASH:
 
664
      goo_canvas_style_set_property (style, goo_canvas_style_line_dash_id, value);
 
665
      recompute_bounds = TRUE;
 
666
      break;
 
667
 
 
668
      /* Font properties. */
 
669
    case PROP_FONT:
 
670
      font_name = g_value_get_string (value);
 
671
      if (font_name)
 
672
        font_desc = pango_font_description_from_string (font_name);
 
673
      g_value_init (&tmpval, PANGO_TYPE_FONT_DESCRIPTION);
 
674
      g_value_take_boxed (&tmpval, font_desc);
 
675
      goo_canvas_style_set_property (style, goo_canvas_style_font_desc_id, &tmpval);
 
676
      g_value_unset (&tmpval);
 
677
      recompute_bounds = TRUE;
 
678
      break;
 
679
    case PROP_FONT_DESC:
 
680
      goo_canvas_style_set_property (style, goo_canvas_style_font_desc_id, value);
 
681
      recompute_bounds = TRUE;
 
682
      break;
 
683
    case PROP_HINT_METRICS:
 
684
      goo_canvas_style_set_property (style, goo_canvas_style_hint_metrics_id, value);
 
685
      recompute_bounds = TRUE;
 
686
      break;
 
687
 
 
688
      /* Convenience properties. */
 
689
    case PROP_STROKE_COLOR:
 
690
      pattern = goo_canvas_create_pattern_from_color_value (value);
 
691
      goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern);
 
692
      break;
 
693
    case PROP_STROKE_COLOR_RGBA:
 
694
      pattern = goo_canvas_create_pattern_from_rgba_value (value);
 
695
      goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern);
 
696
      break;
 
697
    case PROP_STROKE_PIXBUF:
 
698
      pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
 
699
      goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern);
 
700
      break;
 
701
 
 
702
    case PROP_FILL_COLOR:
 
703
      pattern = goo_canvas_create_pattern_from_color_value (value);
 
704
      goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern);
 
705
      break;
 
706
    case PROP_FILL_COLOR_RGBA:
 
707
      pattern = goo_canvas_create_pattern_from_rgba_value (value);
 
708
      goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern);
 
709
      break;
 
710
    case PROP_FILL_PIXBUF:
 
711
      pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
 
712
      goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern);
 
713
      break;
 
714
 
 
715
      /* Other properties. */
 
716
    case PROP_TRANSFORM:
 
717
      g_slice_free (cairo_matrix_t, simple_data->transform);
 
718
      transform = g_value_get_boxed (value);
 
719
      simple_data->transform = goo_cairo_matrix_copy (transform);
 
720
      recompute_bounds = TRUE;
 
721
      break;
 
722
    case PROP_VISIBILITY:
 
723
      simple_data->visibility = g_value_get_enum (value);
 
724
      break;
 
725
    case PROP_VISIBILITY_THRESHOLD:
 
726
      simple_data->visibility_threshold = g_value_get_double (value);
 
727
      break;
 
728
    case PROP_POINTER_EVENTS:
 
729
      simple_data->pointer_events = g_value_get_flags (value);
 
730
      break;
 
731
    case PROP_CAN_FOCUS:
 
732
      simple_data->can_focus = g_value_get_boolean (value);
 
733
      break;
 
734
    case PROP_CLIP_PATH:
 
735
      if (simple_data->clip_path_commands)
 
736
        g_array_free (simple_data->clip_path_commands, TRUE);
 
737
      simple_data->clip_path_commands = goo_canvas_parse_path_data (g_value_get_string (value));
 
738
      recompute_bounds = TRUE;
 
739
      break;
 
740
    case PROP_CLIP_FILL_RULE:
 
741
      simple_data->clip_fill_rule = g_value_get_enum (value);
 
742
      recompute_bounds = TRUE;
 
743
      break;
 
744
    case PROP_TOOLTIP:
 
745
      simple_data->tooltip = g_value_dup_string (value);
 
746
      break;
 
747
    default:
 
748
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
749
      break;
 
750
    }
 
751
 
 
752
  return recompute_bounds;
 
753
}
 
754
 
 
755
 
 
756
static void
 
757
goo_canvas_item_simple_set_property (GObject              *object,
 
758
                                     guint                 prop_id,
 
759
                                     const GValue         *value,
 
760
                                     GParamSpec           *pspec)
 
761
{
 
762
  GooCanvasItem *item = (GooCanvasItem*) object;
 
763
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
 
764
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
765
  GooCanvasItem *parent;
 
766
  AtkObject *accessible;
 
767
  gboolean recompute_bounds;
 
768
 
 
769
  if (simple->model)
 
770
    {
 
771
      g_warning ("Can't set property of a canvas item with a model - set the model property instead");
 
772
      return;
 
773
    }
 
774
 
 
775
  switch (prop_id)
 
776
    {
 
777
    case PROP_PARENT:
 
778
      parent = g_value_get_object (value);
 
779
      goo_canvas_item_remove (item);
 
780
      goo_canvas_item_add_child (parent, item, -1);
 
781
      break;
 
782
    case PROP_TITLE:
 
783
      accessible = atk_gobject_accessible_for_object (object);
 
784
      atk_object_set_name (accessible, g_value_get_string (value));
 
785
      break;
 
786
    case PROP_DESCRIPTION:
 
787
      accessible = atk_gobject_accessible_for_object (object);
 
788
      atk_object_set_description (accessible, g_value_get_string (value));
 
789
      break;
 
790
    default:
 
791
      recompute_bounds = goo_canvas_item_simple_set_common_property (object,
 
792
                                                                     simple_data,
 
793
                                                                     prop_id,
 
794
                                                                     value,
 
795
                                                                     pspec);
 
796
      goo_canvas_item_simple_changed (simple, recompute_bounds);
 
797
      break;
 
798
    }
 
799
}
 
800
 
 
801
 
 
802
static GooCanvas*
 
803
goo_canvas_item_simple_get_canvas  (GooCanvasItem *item)
 
804
{
 
805
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
806
  return simple->canvas;
 
807
}
 
808
 
 
809
 
 
810
static void
 
811
goo_canvas_item_simple_set_canvas  (GooCanvasItem *item,
 
812
                                    GooCanvas     *canvas)
 
813
{
 
814
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
815
  simple->canvas = canvas;
 
816
}
 
817
 
 
818
 
 
819
static GooCanvasItem*
 
820
goo_canvas_item_simple_get_parent (GooCanvasItem   *item)
 
821
{
 
822
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
823
  return simple->parent;
 
824
}
 
825
 
 
826
 
 
827
static void
 
828
goo_canvas_item_simple_set_parent (GooCanvasItem  *item,
 
829
                                   GooCanvasItem  *parent)
 
830
{
 
831
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
832
  GooCanvas *canvas;
 
833
 
 
834
  simple->parent = parent;
 
835
  canvas = parent ? goo_canvas_item_get_canvas (parent) : NULL;
 
836
  goo_canvas_item_set_canvas (item, canvas);
 
837
  simple->need_update = TRUE;
 
838
  simple->need_entire_subtree_update = TRUE;
 
839
}
 
840
 
 
841
 
 
842
/**
 
843
 * goo_canvas_item_simple_changed:
 
844
 * @item: a #GooCanvasItemSimple.
 
845
 * @recompute_bounds: if the item's bounds need to be recomputed.
 
846
 * 
 
847
 * This function is intended to be used by subclasses of #GooCanvasItemSimple.
 
848
 *
 
849
 * It is used as a callback for the "changed" signal of the item models.
 
850
 * It requests an update or redraw of the item as appropriate.
 
851
 **/
 
852
void
 
853
goo_canvas_item_simple_changed    (GooCanvasItemSimple *item,
 
854
                                   gboolean             recompute_bounds)
 
855
{
 
856
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
857
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
858
 
 
859
  if (recompute_bounds)
 
860
    {
 
861
      item->need_entire_subtree_update = TRUE;
 
862
      if (!item->need_update)
 
863
        {
 
864
          goo_canvas_item_request_update ((GooCanvasItem*) item);
 
865
 
 
866
          /* Do this after requesting an update, since GooCanvasGroup will
 
867
             ignore the update request if we do this first. */
 
868
          item->need_update = TRUE;
 
869
        }
 
870
    }
 
871
  else
 
872
    {
 
873
      if (item->canvas)
 
874
        goo_canvas_request_item_redraw (item->canvas, &item->bounds, simple_data->is_static);
 
875
    }
 
876
}
 
877
 
 
878
 
 
879
static gboolean
 
880
goo_canvas_item_simple_get_transform (GooCanvasItem       *item,
 
881
                                      cairo_matrix_t      *matrix)
 
882
{
 
883
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
884
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
885
 
 
886
  if (!simple_data->transform)
 
887
    return FALSE;
 
888
 
 
889
  *matrix = *simple_data->transform;
 
890
  return TRUE;
 
891
}
 
892
 
 
893
 
 
894
static void
 
895
goo_canvas_item_simple_set_transform (GooCanvasItem        *item,
 
896
                                      const cairo_matrix_t *transform)
 
897
{
 
898
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
899
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
900
 
 
901
  if (transform)
 
902
    {
 
903
      if (!simple_data->transform)
 
904
        simple_data->transform = g_slice_new (cairo_matrix_t);
 
905
 
 
906
      *simple_data->transform = *transform;
 
907
    }
 
908
  else
 
909
    {
 
910
      g_slice_free (cairo_matrix_t, simple_data->transform);
 
911
      simple_data->transform = NULL;
 
912
    }
 
913
 
 
914
  goo_canvas_item_simple_changed (simple, TRUE);
 
915
}
 
916
 
 
917
 
 
918
static GooCanvasStyle*
 
919
goo_canvas_item_simple_get_style (GooCanvasItem       *item)
 
920
{
 
921
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
922
 
 
923
  return simple->simple_data->style;
 
924
}
 
925
 
 
926
 
 
927
static void
 
928
goo_canvas_item_simple_set_style (GooCanvasItem  *item,
 
929
                                  GooCanvasStyle *style)
 
930
{
 
931
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
932
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
933
 
 
934
  if (simple_data->style)
 
935
    g_object_unref (simple_data->style);
 
936
 
 
937
  if (style)
 
938
    {
 
939
      simple_data->style = goo_canvas_style_copy (style);
 
940
      simple_data->own_style = TRUE;
 
941
    }
 
942
  else
 
943
    {
 
944
      simple_data->style = NULL;
 
945
      simple_data->own_style = FALSE;
 
946
    }
 
947
 
 
948
  goo_canvas_item_simple_changed (simple, TRUE);
 
949
}
 
950
 
 
951
 
 
952
static void
 
953
goo_canvas_item_simple_get_bounds  (GooCanvasItem   *item,
 
954
                                    GooCanvasBounds *bounds)
 
955
{
 
956
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
957
 
 
958
  if (simple->need_update)
 
959
    goo_canvas_item_ensure_updated (item);
 
960
    
 
961
  *bounds = simple->bounds;
 
962
}
 
963
 
 
964
 
 
965
static GList*
 
966
goo_canvas_item_simple_get_items_at (GooCanvasItem  *item,
 
967
                                     gdouble         x,
 
968
                                     gdouble         y,
 
969
                                     cairo_t        *cr,
 
970
                                     gboolean        is_pointer_event,
 
971
                                     gboolean        parent_visible,
 
972
                                     GList          *found_items)
 
973
{
 
974
  GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (item);
 
975
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
976
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
977
  double user_x = x, user_y = y;
 
978
  cairo_matrix_t matrix;
 
979
  gboolean add_item = FALSE;
 
980
 
 
981
  if (simple->need_update)
 
982
    goo_canvas_item_ensure_updated (item);
 
983
 
 
984
  /* Skip the item if the point isn't in the item's bounds. */
 
985
  if (simple->bounds.x1 > x || simple->bounds.x2 < x
 
986
      || simple->bounds.y1 > y || simple->bounds.y2 < y)
 
987
    return found_items;
 
988
 
 
989
  /* Check if the item should receive events. */
 
990
  if (is_pointer_event)
 
991
    {
 
992
      if (simple_data->pointer_events == GOO_CANVAS_EVENTS_NONE)
 
993
        return found_items;
 
994
      if (simple_data->pointer_events & GOO_CANVAS_EVENTS_VISIBLE_MASK
 
995
          && (!parent_visible
 
996
              || simple_data->visibility <= GOO_CANVAS_ITEM_INVISIBLE
 
997
              || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
 
998
                  && simple->canvas->scale < simple_data->visibility_threshold)))
 
999
        return found_items;
 
1000
    }
 
1001
 
 
1002
  cairo_save (cr);
 
1003
  if (simple_data->transform)
 
1004
    cairo_transform (cr, simple_data->transform);
 
1005
 
 
1006
  cairo_device_to_user (cr, &user_x, &user_y);
 
1007
 
 
1008
  /* Remove any current translation, to avoid the 16-bit cairo limit. */
 
1009
  cairo_get_matrix (cr, &matrix);
 
1010
  matrix.x0 = matrix.y0 = 0.0;
 
1011
  cairo_set_matrix (cr, &matrix);
 
1012
 
 
1013
  /* If the item has a clip path, check if the point is inside it. */
 
1014
  if (simple_data->clip_path_commands)
 
1015
    {
 
1016
      goo_canvas_create_path (simple_data->clip_path_commands, cr);
 
1017
      cairo_set_fill_rule (cr, simple_data->clip_fill_rule);
 
1018
      if (!cairo_in_fill (cr, user_x, user_y))
 
1019
        {
 
1020
          cairo_restore (cr);
 
1021
          return found_items;
 
1022
        }
 
1023
    }
 
1024
 
 
1025
  add_item = class->simple_is_item_at (simple, user_x, user_y, cr,
 
1026
                                       is_pointer_event);
 
1027
 
 
1028
  cairo_restore (cr);
 
1029
 
 
1030
  if (add_item)
 
1031
    return g_list_prepend (found_items, item);
 
1032
  else
 
1033
    return found_items;
 
1034
}
 
1035
 
 
1036
 
 
1037
static gboolean
 
1038
goo_canvas_item_simple_default_is_item_at (GooCanvasItemSimple *simple,
 
1039
                                           double               x,
 
1040
                                           double               y,
 
1041
                                           cairo_t             *cr,
 
1042
                                           gboolean             is_pointer_event)
 
1043
{
 
1044
  GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (simple);
 
1045
 
 
1046
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1047
  GooCanvasPointerEvents pointer_events = GOO_CANVAS_EVENTS_ALL;
 
1048
 
 
1049
  if (is_pointer_event)
 
1050
    pointer_events = simple_data->pointer_events;
 
1051
 
 
1052
  /* Use the virtual method subclasses define to create the path. */
 
1053
  class->simple_create_path (simple, cr);
 
1054
 
 
1055
  if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events))
 
1056
    return TRUE;
 
1057
 
 
1058
  return FALSE;
 
1059
}
 
1060
 
 
1061
 
 
1062
static gboolean
 
1063
goo_canvas_item_simple_is_visible  (GooCanvasItem   *item)
 
1064
{
 
1065
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
1066
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1067
 
 
1068
  if (simple_data->visibility <= GOO_CANVAS_ITEM_INVISIBLE
 
1069
      || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
 
1070
          && simple->canvas->scale < simple_data->visibility_threshold))
 
1071
    return FALSE;
 
1072
 
 
1073
  if (simple->parent)
 
1074
    return goo_canvas_item_is_visible (simple->parent);
 
1075
 
 
1076
  return TRUE;
 
1077
}
 
1078
 
 
1079
 
 
1080
static gboolean
 
1081
goo_canvas_item_simple_get_is_static  (GooCanvasItem   *item)
 
1082
{
 
1083
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
1084
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1085
 
 
1086
  return simple_data->is_static;
 
1087
}
 
1088
 
 
1089
 
 
1090
static void
 
1091
goo_canvas_item_simple_set_is_static  (GooCanvasItem   *item,
 
1092
                                       gboolean         is_static)
 
1093
{
 
1094
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
1095
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1096
 
 
1097
  simple_data->is_static = is_static;
 
1098
}
 
1099
 
 
1100
 
 
1101
/**
 
1102
 * goo_canvas_item_simple_check_style:
 
1103
 * @item: a #GooCanvasItemSimple.
 
1104
 * 
 
1105
 * This function is intended to be used by subclasses of #GooCanvasItemSimple,
 
1106
 * typically in their update() or get_requested_area() methods.
 
1107
 *
 
1108
 * It ensures that the item's style is setup correctly. If the item has its
 
1109
 * own #GooCanvasStyle it makes sure the parent is set correctly. If it
 
1110
 * doesn't have its own style it uses the parent item's style.
 
1111
 **/
 
1112
void
 
1113
goo_canvas_item_simple_check_style (GooCanvasItemSimple *item)
 
1114
{
 
1115
  GooCanvasItemSimpleData *simple_data = item->simple_data;
 
1116
  GooCanvasStyle *parent_style = NULL;
 
1117
 
 
1118
  if (item->parent)
 
1119
    parent_style = goo_canvas_item_get_style (item->parent);
 
1120
 
 
1121
  if (simple_data->own_style)
 
1122
    {
 
1123
      goo_canvas_style_set_parent (simple_data->style, parent_style);
 
1124
    }
 
1125
  else if (simple_data->style != parent_style)
 
1126
    {
 
1127
      /* The item doesn't have its own style so we use the parent's (though
 
1128
         that may also be NULL). */
 
1129
      if (simple_data->style)
 
1130
        g_object_unref (simple_data->style);
 
1131
 
 
1132
      simple_data->style = parent_style;
 
1133
 
 
1134
      if (parent_style)
 
1135
        g_object_ref (parent_style);
 
1136
    }
 
1137
}
 
1138
 
 
1139
 
 
1140
static void
 
1141
goo_canvas_item_simple_update_internal  (GooCanvasItemSimple *simple,
 
1142
                                         cairo_t             *cr)
 
1143
{
 
1144
  GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (simple);
 
1145
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1146
  GooCanvasBounds tmp_bounds;
 
1147
  cairo_matrix_t transform;
 
1148
 
 
1149
  simple->need_update = FALSE;
 
1150
 
 
1151
  goo_canvas_item_simple_check_style (simple);
 
1152
 
 
1153
  cairo_get_matrix (cr, &transform);
 
1154
 
 
1155
  class->simple_update (simple, cr);
 
1156
 
 
1157
  /* Modify the extents by the item's clip path. */
 
1158
  if (simple_data->clip_path_commands)
 
1159
    {
 
1160
      cairo_identity_matrix (cr);
 
1161
      goo_canvas_create_path (simple_data->clip_path_commands, cr);
 
1162
      cairo_set_fill_rule (cr, simple_data->clip_fill_rule);
 
1163
      cairo_fill_extents (cr, &tmp_bounds.x1, &tmp_bounds.y1,
 
1164
                          &tmp_bounds.x2, &tmp_bounds.y2);
 
1165
      simple->bounds.x1 = MAX (simple->bounds.x1, tmp_bounds.x1);
 
1166
      simple->bounds.y1 = MAX (simple->bounds.y1, tmp_bounds.y1);
 
1167
      simple->bounds.x2 = MIN (simple->bounds.x2, tmp_bounds.x2);
 
1168
      simple->bounds.y2 = MIN (simple->bounds.y2, tmp_bounds.y2);
 
1169
 
 
1170
      if (simple->bounds.x1 > simple->bounds.x2)
 
1171
        simple->bounds.x2 = simple->bounds.x1;
 
1172
      if (simple->bounds.y1 > simple->bounds.y2)
 
1173
        simple->bounds.y2 = simple->bounds.y1;
 
1174
    }
 
1175
 
 
1176
  cairo_set_matrix (cr, &transform);
 
1177
}
 
1178
 
 
1179
 
 
1180
static void
 
1181
goo_canvas_item_simple_default_update (GooCanvasItemSimple   *simple,
 
1182
                                       cairo_t               *cr)
 
1183
{
 
1184
  GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (simple);
 
1185
 
 
1186
  /* Use the identity matrix to get the bounds completely in user space. */
 
1187
  cairo_identity_matrix (cr);
 
1188
 
 
1189
  class->simple_create_path (simple, cr);
 
1190
  goo_canvas_item_simple_get_path_bounds (simple, cr, &simple->bounds);
 
1191
}
 
1192
 
 
1193
 
 
1194
static void
 
1195
goo_canvas_item_simple_update  (GooCanvasItem   *item,
 
1196
                                gboolean         entire_tree,
 
1197
                                cairo_t         *cr,
 
1198
                                GooCanvasBounds *bounds)
 
1199
{
 
1200
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
1201
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1202
  cairo_matrix_t matrix;
 
1203
  double x_offset, y_offset;
 
1204
 
 
1205
  if (entire_tree || simple->need_update)
 
1206
    {
 
1207
      /* Request a redraw of the existing bounds. */
 
1208
      goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
 
1209
 
 
1210
      cairo_save (cr);
 
1211
      if (simple_data->transform)
 
1212
        cairo_transform (cr, simple_data->transform);
 
1213
 
 
1214
      /* Remove any current translation, to avoid the 16-bit cairo limit. */
 
1215
      cairo_get_matrix (cr, &matrix);
 
1216
      x_offset = matrix.x0;
 
1217
      y_offset = matrix.y0;
 
1218
      matrix.x0 = matrix.y0 = 0.0;
 
1219
      cairo_set_matrix (cr, &matrix);
 
1220
 
 
1221
      goo_canvas_item_simple_update_internal (simple, cr);
 
1222
 
 
1223
      goo_canvas_item_simple_user_bounds_to_device (simple, cr,
 
1224
                                                    &simple->bounds);
 
1225
 
 
1226
      /* Add the translation back to the bounds. */
 
1227
      simple->bounds.x1 += x_offset;
 
1228
      simple->bounds.y1 += y_offset;
 
1229
      simple->bounds.x2 += x_offset;
 
1230
      simple->bounds.y2 += y_offset;
 
1231
 
 
1232
      cairo_restore (cr);
 
1233
 
 
1234
      /* Request a redraw of the new bounds. */
 
1235
      goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
 
1236
    }
 
1237
 
 
1238
  *bounds = simple->bounds;
 
1239
}
 
1240
 
 
1241
 
 
1242
static gboolean
 
1243
goo_canvas_item_simple_get_requested_area (GooCanvasItem    *item,
 
1244
                                           cairo_t          *cr,
 
1245
                                           GooCanvasBounds  *requested_area)
 
1246
{
 
1247
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
1248
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1249
  cairo_matrix_t matrix;
 
1250
  double x_offset, y_offset;
 
1251
 
 
1252
  /* Request a redraw of the existing bounds. */
 
1253
  goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
 
1254
 
 
1255
  cairo_save (cr);
 
1256
  if (simple_data->transform)
 
1257
    cairo_transform (cr, simple_data->transform);
 
1258
 
 
1259
  /* Remove any current translation, to avoid the 16-bit cairo limit. */
 
1260
  cairo_get_matrix (cr, &matrix);
 
1261
  x_offset = matrix.x0;
 
1262
  y_offset = matrix.y0;
 
1263
  matrix.x0 = matrix.y0 = 0.0;
 
1264
  cairo_set_matrix (cr, &matrix);
 
1265
 
 
1266
  goo_canvas_item_simple_update_internal (simple, cr);
 
1267
 
 
1268
  if (simple->simple_data->visibility == GOO_CANVAS_ITEM_HIDDEN)
 
1269
    {
 
1270
      simple->bounds.x1 = simple->bounds.x2 = 0.0;
 
1271
      simple->bounds.y1 = simple->bounds.y2 = 0.0;
 
1272
      cairo_restore (cr);
 
1273
      return FALSE;
 
1274
    }
 
1275
 
 
1276
  /* FIXME: Maybe optimize by just converting the offsets to user space
 
1277
     and adding them? */
 
1278
 
 
1279
  /* Convert to device space. */
 
1280
  cairo_user_to_device (cr, &simple->bounds.x1, &simple->bounds.y1);
 
1281
  cairo_user_to_device (cr, &simple->bounds.x2, &simple->bounds.y2);
 
1282
 
 
1283
  /* Add the translation back to the bounds. */
 
1284
  simple->bounds.x1 += x_offset;
 
1285
  simple->bounds.y1 += y_offset;
 
1286
  simple->bounds.x2 += x_offset;
 
1287
  simple->bounds.y2 += y_offset;
 
1288
 
 
1289
  /* Restore the item's proper transformation matrix. */
 
1290
  matrix.x0 = x_offset;
 
1291
  matrix.y0 = y_offset;
 
1292
  cairo_set_matrix (cr, &matrix);
 
1293
 
 
1294
  /* Convert back to user space. */
 
1295
  cairo_device_to_user (cr, &simple->bounds.x1, &simple->bounds.y1);
 
1296
  cairo_device_to_user (cr, &simple->bounds.x2, &simple->bounds.y2);
 
1297
 
 
1298
 
 
1299
  /* Copy the user bounds to the requested area. */
 
1300
  *requested_area = simple->bounds;
 
1301
 
 
1302
  /* Convert to the parent's coordinate space. */
 
1303
  goo_canvas_item_simple_user_bounds_to_parent (simple, cr, requested_area);
 
1304
 
 
1305
  /* Convert the item's bounds to device space. */
 
1306
  goo_canvas_item_simple_user_bounds_to_device (simple, cr, &simple->bounds);
 
1307
 
 
1308
  cairo_restore (cr);
 
1309
 
 
1310
  return TRUE;
 
1311
}
 
1312
 
 
1313
 
 
1314
static void
 
1315
goo_canvas_item_simple_allocate_area      (GooCanvasItem         *item,
 
1316
                                           cairo_t               *cr,
 
1317
                                           const GooCanvasBounds *requested_area,
 
1318
                                           const GooCanvasBounds *allocated_area,
 
1319
                                           gdouble                x_offset,
 
1320
                                           gdouble                y_offset)
 
1321
{
 
1322
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
1323
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1324
 
 
1325
  /* Simple items can't resize at all, so we just adjust the bounds x & y
 
1326
     positions here, and let the item be clipped if necessary. */
 
1327
  simple->bounds.x1 += x_offset;
 
1328
  simple->bounds.y1 += y_offset;
 
1329
  simple->bounds.x2 += x_offset;
 
1330
  simple->bounds.y2 += y_offset;
 
1331
 
 
1332
  /* Request a redraw of the new bounds. */
 
1333
  goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
 
1334
}
 
1335
 
 
1336
 
 
1337
static void
 
1338
goo_canvas_item_simple_paint (GooCanvasItem         *item,
 
1339
                              cairo_t               *cr,
 
1340
                              const GooCanvasBounds *bounds,
 
1341
                              gdouble                scale)
 
1342
{
 
1343
  GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (item);
 
1344
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
1345
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1346
 
 
1347
  /* Skip the item if the bounds don't intersect the expose rectangle. */
 
1348
  if (simple->bounds.x1 > bounds->x2 || simple->bounds.x2 < bounds->x1
 
1349
      || simple->bounds.y1 > bounds->y2 || simple->bounds.y2 < bounds->y1)
 
1350
    return;
 
1351
 
 
1352
  /* Check if the item should be visible. */
 
1353
  if (simple_data->visibility <= GOO_CANVAS_ITEM_INVISIBLE
 
1354
      || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
 
1355
          && scale < simple_data->visibility_threshold))
 
1356
    return;
 
1357
 
 
1358
  cairo_save (cr);
 
1359
  if (simple_data->transform)
 
1360
    cairo_transform (cr, simple_data->transform);
 
1361
 
 
1362
  /* Clip with the item's clip path, if it is set. */
 
1363
  if (simple_data->clip_path_commands)
 
1364
    {
 
1365
      goo_canvas_create_path (simple_data->clip_path_commands, cr);
 
1366
      cairo_set_fill_rule (cr, simple_data->clip_fill_rule);
 
1367
      cairo_clip (cr);
 
1368
    }
 
1369
 
 
1370
  class->simple_paint (simple, cr, bounds);
 
1371
 
 
1372
  cairo_restore (cr);
 
1373
}
 
1374
 
 
1375
 
 
1376
static void
 
1377
goo_canvas_item_simple_default_paint (GooCanvasItemSimple   *simple,
 
1378
                                      cairo_t               *cr,
 
1379
                                      const GooCanvasBounds *bounds)
 
1380
{
 
1381
  GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (simple);
 
1382
 
 
1383
  class->simple_create_path (simple, cr);
 
1384
  goo_canvas_item_simple_paint_path (simple, cr);
 
1385
}
 
1386
 
 
1387
 
 
1388
static void
 
1389
goo_canvas_item_simple_default_create_path (GooCanvasItemSimple   *simple,
 
1390
                                            cairo_t               *cr)
 
1391
{
 
1392
  /* Do nothing. */
 
1393
}
 
1394
 
 
1395
 
 
1396
static void
 
1397
goo_canvas_item_simple_title_changed (GooCanvasItemModelSimple *smodel,
 
1398
                                      GParamSpec               *pspec,
 
1399
                                      GooCanvasItemSimple      *item)
 
1400
{
 
1401
  AtkObject *accessible;
 
1402
 
 
1403
  accessible = atk_gobject_accessible_for_object (G_OBJECT (item));
 
1404
  atk_object_set_name (accessible, smodel->title);
 
1405
}
 
1406
 
 
1407
 
 
1408
static void
 
1409
goo_canvas_item_simple_description_changed (GooCanvasItemModelSimple *smodel,
 
1410
                                            GParamSpec               *pspec,
 
1411
                                            GooCanvasItemSimple      *item)
 
1412
{
 
1413
  AtkObject *accessible;
 
1414
 
 
1415
  accessible = atk_gobject_accessible_for_object (G_OBJECT (item));
 
1416
  atk_object_set_description (accessible, smodel->description);
 
1417
}
 
1418
 
 
1419
 
 
1420
static void
 
1421
goo_canvas_item_simple_setup_accessibility (GooCanvasItemSimple      *item)
 
1422
{
 
1423
  GooCanvasItemModelSimple *smodel = item->model;
 
1424
  AtkObject *accessible;
 
1425
 
 
1426
  accessible = atk_gobject_accessible_for_object (G_OBJECT (item));
 
1427
  if (!ATK_IS_NO_OP_OBJECT (accessible))
 
1428
    {
 
1429
      if (smodel->title)
 
1430
        atk_object_set_name (accessible, smodel->title);
 
1431
      if (smodel->description)
 
1432
        atk_object_set_description (accessible, smodel->description);
 
1433
 
 
1434
      g_signal_connect (smodel, "notify::title",
 
1435
                        G_CALLBACK (goo_canvas_item_simple_title_changed),
 
1436
                        item);
 
1437
      g_signal_connect (smodel, "notify::description",
 
1438
                        G_CALLBACK (goo_canvas_item_simple_description_changed),
 
1439
                        item);
 
1440
    }
 
1441
}
 
1442
 
 
1443
 
 
1444
static void
 
1445
goo_canvas_item_model_simple_changed (GooCanvasItemModelSimple *smodel,
 
1446
                                      gboolean                  recompute_bounds,
 
1447
                                      GooCanvasItemSimple      *simple)
 
1448
{
 
1449
  goo_canvas_item_simple_changed (simple, recompute_bounds);
 
1450
}
 
1451
 
 
1452
 
 
1453
static GooCanvasItemModel*
 
1454
goo_canvas_item_simple_get_model    (GooCanvasItem      *item)
 
1455
{
 
1456
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
1457
  return (GooCanvasItemModel*) simple->model;
 
1458
}
 
1459
 
 
1460
 
 
1461
/**
 
1462
 * goo_canvas_item_simple_set_model:
 
1463
 * @item: a #GooCanvasItemSimple.
 
1464
 * @model: the model that @item will view.
 
1465
 * 
 
1466
 * This function should be called by subclasses of #GooCanvasItemSimple
 
1467
 * in their set_model() method.
 
1468
 **/
 
1469
void
 
1470
goo_canvas_item_simple_set_model (GooCanvasItemSimple  *item,
 
1471
                                  GooCanvasItemModel   *model)
 
1472
{
 
1473
  g_return_if_fail (model != NULL);
 
1474
 
 
1475
  goo_canvas_item_simple_reset_model (item);
 
1476
  goo_canvas_item_simple_free_data (item->simple_data);
 
1477
  g_slice_free (GooCanvasItemSimpleData, item->simple_data);
 
1478
 
 
1479
  item->model = g_object_ref (model);
 
1480
  item->simple_data = &item->model->simple_data;
 
1481
 
 
1482
  if (accessibility_enabled)
 
1483
    goo_canvas_item_simple_setup_accessibility (item);
 
1484
 
 
1485
  g_signal_connect (model, "changed",
 
1486
                    G_CALLBACK (goo_canvas_item_model_simple_changed),
 
1487
                    item);
 
1488
}
 
1489
 
 
1490
 
 
1491
static void
 
1492
goo_canvas_item_simple_set_model_internal    (GooCanvasItem      *item,
 
1493
                                              GooCanvasItemModel *model)
 
1494
{
 
1495
  goo_canvas_item_simple_set_model ((GooCanvasItemSimple*) item, model);
 
1496
}
 
1497
 
 
1498
 
 
1499
static gboolean
 
1500
goo_canvas_item_simple_query_tooltip (GooCanvasItem  *item,
 
1501
                                      gdouble         x,
 
1502
                                      gdouble         y,
 
1503
                                      gboolean        keyboard_tip,
 
1504
                                      GtkTooltip     *tooltip)
 
1505
{
 
1506
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
 
1507
  GooCanvasItemSimpleData *simple_data = simple->simple_data;
 
1508
 
 
1509
  if (simple_data->tooltip)
 
1510
    {
 
1511
      gtk_tooltip_set_markup (tooltip, simple_data->tooltip);
 
1512
      return TRUE;
 
1513
    }
 
1514
 
 
1515
  return FALSE;
 
1516
}
 
1517
 
 
1518
 
 
1519
static void
 
1520
canvas_item_interface_init (GooCanvasItemIface *iface)
 
1521
{
 
1522
  iface->get_canvas         = goo_canvas_item_simple_get_canvas;
 
1523
  iface->set_canvas         = goo_canvas_item_simple_set_canvas;
 
1524
 
 
1525
  iface->get_parent         = goo_canvas_item_simple_get_parent;
 
1526
  iface->set_parent         = goo_canvas_item_simple_set_parent;
 
1527
  iface->get_bounds         = goo_canvas_item_simple_get_bounds;
 
1528
  iface->get_items_at       = goo_canvas_item_simple_get_items_at;
 
1529
  iface->update             = goo_canvas_item_simple_update;
 
1530
  iface->get_requested_area = goo_canvas_item_simple_get_requested_area;
 
1531
  iface->allocate_area      = goo_canvas_item_simple_allocate_area;
 
1532
  iface->paint              = goo_canvas_item_simple_paint;
 
1533
 
 
1534
  iface->get_transform      = goo_canvas_item_simple_get_transform;
 
1535
  iface->set_transform      = goo_canvas_item_simple_set_transform;
 
1536
  iface->get_style          = goo_canvas_item_simple_get_style;
 
1537
  iface->set_style          = goo_canvas_item_simple_set_style;
 
1538
  iface->is_visible         = goo_canvas_item_simple_is_visible;
 
1539
  iface->get_is_static      = goo_canvas_item_simple_get_is_static;
 
1540
  iface->set_is_static      = goo_canvas_item_simple_set_is_static;
 
1541
 
 
1542
  iface->get_model          = goo_canvas_item_simple_get_model;
 
1543
  iface->set_model          = goo_canvas_item_simple_set_model_internal;
 
1544
 
 
1545
  iface->query_tooltip      = goo_canvas_item_simple_query_tooltip;
 
1546
}
 
1547
 
 
1548
 
 
1549
/**
 
1550
 * goo_canvas_item_simple_paint_path:
 
1551
 * @item: a #GooCanvasItemSimple.
 
1552
 * @cr: a cairo context.
 
1553
 * 
 
1554
 * This function is intended to be used by subclasses of #GooCanvasItemSimple.
 
1555
 *
 
1556
 * It paints the current path, using the item's style settings.
 
1557
 **/
 
1558
void
 
1559
goo_canvas_item_simple_paint_path (GooCanvasItemSimple *item,
 
1560
                                   cairo_t             *cr)
 
1561
{
 
1562
  GooCanvasStyle *style = item->simple_data->style;
 
1563
 
 
1564
  if (goo_canvas_style_set_fill_options (style, cr))
 
1565
    cairo_fill_preserve (cr);
 
1566
 
 
1567
  if (goo_canvas_style_set_stroke_options (style, cr))
 
1568
    cairo_stroke (cr);
 
1569
 
 
1570
  cairo_new_path (cr);
 
1571
}
 
1572
 
 
1573
 
 
1574
/* Returns the bounds of the path, using the item's stroke and fill options,
 
1575
   in device coords. Note that the bounds include both the stroke and the
 
1576
   fill extents, even if they will not be painted. (We need this to handle
 
1577
   the "pointer-events" property.) */
 
1578
/**
 
1579
 * goo_canvas_item_simple_get_path_bounds:
 
1580
 * @item: a #GooCanvasItemSimple.
 
1581
 * @cr: a cairo context.
 
1582
 * @bounds: the #GooCanvasBounds struct to store the resulting bounding box.
 
1583
 * 
 
1584
 * This function is intended to be used by subclasses of #GooCanvasItemSimple,
 
1585
 * typically in their update() or get_requested_area() methods.
 
1586
 *
 
1587
 * It calculates the bounds of the current path, using the item's style
 
1588
 * settings, and stores the results in the given #GooCanvasBounds struct.
 
1589
 *
 
1590
 * The returned bounds contains the bounding box of the path in device space,
 
1591
 * converted to user space coordinates. To calculate the bounds completely in
 
1592
 * user space, use cairo_identity_matrix() to temporarily reset the current
 
1593
 * transformation matrix to the identity matrix.
 
1594
 **/
 
1595
void
 
1596
goo_canvas_item_simple_get_path_bounds (GooCanvasItemSimple *item,
 
1597
                                        cairo_t             *cr,
 
1598
                                        GooCanvasBounds     *bounds)
 
1599
{
 
1600
  GooCanvasStyle *style = item->simple_data->style;
 
1601
  GooCanvasBounds fill_bounds, stroke_bounds;
 
1602
 
 
1603
  /* Calculate the filled extents. */
 
1604
  goo_canvas_style_set_fill_options (style, cr);
 
1605
  cairo_fill_extents (cr, &fill_bounds.x1, &fill_bounds.y1,
 
1606
                      &fill_bounds.x2, &fill_bounds.y2);
 
1607
 
 
1608
  /* Check the stroke. */
 
1609
  goo_canvas_style_set_stroke_options (style, cr);
 
1610
  cairo_stroke_extents (cr, &stroke_bounds.x1, &stroke_bounds.y1,
 
1611
                        &stroke_bounds.x2, &stroke_bounds.y2);
 
1612
 
 
1613
  /* Workaround for cairo < 1.4.0. It used to just return odd values
 
1614
     if the path had empty bounds. This fix will work, but only if there is
 
1615
     no transform currently set, since cairo will convert to user space. */
 
1616
  if (cairo_version () < CAIRO_VERSION_ENCODE (1, 4, 0))
 
1617
    {
 
1618
      if (fill_bounds.x1 == 32767.0 && fill_bounds.x2 == -32768.0)
 
1619
        fill_bounds.x1 = fill_bounds.x2 = 0.0;
 
1620
      if (stroke_bounds.x1 == 32767.0 && stroke_bounds.x2 == -32768.0)
 
1621
        stroke_bounds.x1 = stroke_bounds.x2 = 0.0;
 
1622
    }
 
1623
 
 
1624
  if (fill_bounds.x1 == 0.0 && fill_bounds.x2 == 0.0)
 
1625
    {
 
1626
      /* The fill bounds are empty so just use the stroke bounds.
 
1627
         If the stroke bounds are also empty the bounds will be all 0.0. */
 
1628
      bounds->x1 = MIN (stroke_bounds.x1, stroke_bounds.x2);
 
1629
      bounds->x2 = MAX (stroke_bounds.x1, stroke_bounds.x2);
 
1630
      bounds->y1 = MIN (stroke_bounds.y1, stroke_bounds.y2);
 
1631
      bounds->y2 = MAX (stroke_bounds.y1, stroke_bounds.y2);
 
1632
    }
 
1633
  else if (stroke_bounds.x1 == 0.0 && stroke_bounds.x2 == 0.0)
 
1634
    {
 
1635
      /* The stroke bounds are empty so just use the fill bounds. */
 
1636
      bounds->x1 = MIN (fill_bounds.x1, fill_bounds.x2);
 
1637
      bounds->x2 = MAX (fill_bounds.x1, fill_bounds.x2);
 
1638
      bounds->y1 = MIN (fill_bounds.y1, fill_bounds.y2);
 
1639
      bounds->y2 = MAX (fill_bounds.y1, fill_bounds.y2);
 
1640
    }
 
1641
  else
 
1642
    {
 
1643
      /* Both fill & stoke bounds are non-empty so combine them. */
 
1644
      bounds->x1 = MIN (fill_bounds.x1, fill_bounds.x2);
 
1645
      bounds->x2 = MAX (fill_bounds.x1, fill_bounds.x2);
 
1646
      bounds->y1 = MIN (fill_bounds.y1, fill_bounds.y2);
 
1647
      bounds->y2 = MAX (fill_bounds.y1, fill_bounds.y2);
 
1648
 
 
1649
      bounds->x1 = MIN (bounds->x1, stroke_bounds.x1);
 
1650
      bounds->x1 = MIN (bounds->x1, stroke_bounds.x2);
 
1651
 
 
1652
      bounds->x2 = MAX (bounds->x2, stroke_bounds.x1);
 
1653
      bounds->x2 = MAX (bounds->x2, stroke_bounds.x2);
 
1654
 
 
1655
      bounds->y1 = MIN (bounds->y1, stroke_bounds.y1);
 
1656
      bounds->y1 = MIN (bounds->y1, stroke_bounds.y2);
 
1657
 
 
1658
      bounds->y2 = MAX (bounds->y2, stroke_bounds.y1);
 
1659
      bounds->y2 = MAX (bounds->y2, stroke_bounds.y2);
 
1660
    }
 
1661
}
 
1662
 
 
1663
 
 
1664
/**
 
1665
 * goo_canvas_item_simple_user_bounds_to_device:
 
1666
 * @item: a #GooCanvasItemSimple.
 
1667
 * @cr: a cairo context.
 
1668
 * @bounds: the bounds of the item, in the item's coordinate space.
 
1669
 * 
 
1670
 * This function is intended to be used by subclasses of #GooCanvasItemSimple,
 
1671
 * typically in their update() or get_requested_area() methods.
 
1672
 *
 
1673
 * It converts the item's bounds to a bounding box in the canvas (device)
 
1674
 * coordinate space.
 
1675
 **/
 
1676
void
 
1677
goo_canvas_item_simple_user_bounds_to_device (GooCanvasItemSimple *item,
 
1678
                                              cairo_t             *cr,
 
1679
                                              GooCanvasBounds     *bounds)
 
1680
{
 
1681
  GooCanvasBounds tmp_bounds = *bounds, tmp_bounds2 = *bounds;
 
1682
 
 
1683
  /* Convert the top-left and bottom-right corners to device coords. */
 
1684
  cairo_user_to_device (cr, &tmp_bounds.x1, &tmp_bounds.y1);
 
1685
  cairo_user_to_device (cr, &tmp_bounds.x2, &tmp_bounds.y2);
 
1686
 
 
1687
  /* Now convert the top-right and bottom-left corners. */
 
1688
  cairo_user_to_device (cr, &tmp_bounds2.x1, &tmp_bounds2.y2);
 
1689
  cairo_user_to_device (cr, &tmp_bounds2.x2, &tmp_bounds2.y1);
 
1690
 
 
1691
  /* Calculate the minimum x coordinate seen and put in x1. */
 
1692
  bounds->x1 = MIN (tmp_bounds.x1, tmp_bounds.x2);
 
1693
  bounds->x1 = MIN (bounds->x1, tmp_bounds2.x1);
 
1694
  bounds->x1 = MIN (bounds->x1, tmp_bounds2.x2);
 
1695
 
 
1696
  /* Calculate the maximum x coordinate seen and put in x2. */
 
1697
  bounds->x2 = MAX (tmp_bounds.x1, tmp_bounds.x2);
 
1698
  bounds->x2 = MAX (bounds->x2, tmp_bounds2.x1);
 
1699
  bounds->x2 = MAX (bounds->x2, tmp_bounds2.x2);
 
1700
 
 
1701
  /* Calculate the minimum y coordinate seen and put in y1. */
 
1702
  bounds->y1 = MIN (tmp_bounds.y1, tmp_bounds.y2);
 
1703
  bounds->y1 = MIN (bounds->y1, tmp_bounds2.y1);
 
1704
  bounds->y1 = MIN (bounds->y1, tmp_bounds2.y2);
 
1705
 
 
1706
  /* Calculate the maximum y coordinate seen and put in y2. */
 
1707
  bounds->y2 = MAX (tmp_bounds.y1, tmp_bounds.y2);
 
1708
  bounds->y2 = MAX (bounds->y2, tmp_bounds2.y1);
 
1709
  bounds->y2 = MAX (bounds->y2, tmp_bounds2.y2);
 
1710
}
 
1711
 
 
1712
 
 
1713
/**
 
1714
 * goo_canvas_item_simple_user_bounds_to_parent:
 
1715
 * @item: a #GooCanvasItemSimple.
 
1716
 * @cr: a cairo context.
 
1717
 * @bounds: the bounds of the item, in the item's coordinate space.
 
1718
 * 
 
1719
 * This function is intended to be used by subclasses of #GooCanvasItemSimple,
 
1720
 * typically in their get_requested_area() method.
 
1721
 *
 
1722
 * It converts the item's bounds to a bounding box in its parent's coordinate
 
1723
 * space. If the item has no transformation matrix set then no conversion is
 
1724
 * needed.
 
1725
 **/
 
1726
void
 
1727
goo_canvas_item_simple_user_bounds_to_parent (GooCanvasItemSimple *item,
 
1728
                                              cairo_t             *cr,
 
1729
                                              GooCanvasBounds     *bounds)
 
1730
{
 
1731
  GooCanvasItemSimpleData *simple_data = item->simple_data;
 
1732
  cairo_matrix_t *transform = simple_data->transform;
 
1733
  GooCanvasBounds tmp_bounds, tmp_bounds2;
 
1734
 
 
1735
  if (!transform)
 
1736
    return;
 
1737
 
 
1738
  tmp_bounds = tmp_bounds2 = *bounds;
 
1739
 
 
1740
  /* Convert the top-left and bottom-right corners to parent coords. */
 
1741
  cairo_matrix_transform_point (transform, &tmp_bounds.x1, &tmp_bounds.y1);
 
1742
  cairo_matrix_transform_point (transform, &tmp_bounds.x2, &tmp_bounds.y2);
 
1743
 
 
1744
  /* Now convert the top-right and bottom-left corners. */
 
1745
  cairo_matrix_transform_point (transform, &tmp_bounds2.x1, &tmp_bounds2.y2);
 
1746
  cairo_matrix_transform_point (transform, &tmp_bounds2.x2, &tmp_bounds2.y1);
 
1747
 
 
1748
  /* Calculate the minimum x coordinate seen and put in x1. */
 
1749
  bounds->x1 = MIN (tmp_bounds.x1, tmp_bounds.x2);
 
1750
  bounds->x1 = MIN (bounds->x1, tmp_bounds2.x1);
 
1751
  bounds->x1 = MIN (bounds->x1, tmp_bounds2.x2);
 
1752
 
 
1753
  /* Calculate the maximum x coordinate seen and put in x2. */
 
1754
  bounds->x2 = MAX (tmp_bounds.x1, tmp_bounds.x2);
 
1755
  bounds->x2 = MAX (bounds->x2, tmp_bounds2.x1);
 
1756
  bounds->x2 = MAX (bounds->x2, tmp_bounds2.x2);
 
1757
 
 
1758
  /* Calculate the minimum y coordinate seen and put in y1. */
 
1759
  bounds->y1 = MIN (tmp_bounds.y1, tmp_bounds.y2);
 
1760
  bounds->y1 = MIN (bounds->y1, tmp_bounds2.y1);
 
1761
  bounds->y1 = MIN (bounds->y1, tmp_bounds2.y2);
 
1762
 
 
1763
  /* Calculate the maximum y coordinate seen and put in y2. */
 
1764
  bounds->y2 = MAX (tmp_bounds.y1, tmp_bounds.y2);
 
1765
  bounds->y2 = MAX (bounds->y2, tmp_bounds2.y1);
 
1766
  bounds->y2 = MAX (bounds->y2, tmp_bounds2.y2);
 
1767
}
 
1768
 
 
1769
 
 
1770
/**
 
1771
 * goo_canvas_item_simple_check_in_path:
 
1772
 * @item: a #GooCanvasItemSimple.
 
1773
 * @x: the x coordinate of the point.
 
1774
 * @y: the y coordinate of the point.
 
1775
 * @cr: a cairo context.
 
1776
 * @pointer_events: specifies which parts of the path to check.
 
1777
 * 
 
1778
 * This function is intended to be used by subclasses of #GooCanvasItemSimple.
 
1779
 *
 
1780
 * It checks if the given point is in the current path, using the item's
 
1781
 * style settings.
 
1782
 * 
 
1783
 * Returns: %TRUE if the given point is in the current path.
 
1784
 **/
 
1785
gboolean
 
1786
goo_canvas_item_simple_check_in_path (GooCanvasItemSimple   *item,
 
1787
                                      gdouble                x,
 
1788
                                      gdouble                y,
 
1789
                                      cairo_t               *cr,
 
1790
                                      GooCanvasPointerEvents pointer_events)
 
1791
{
 
1792
  GooCanvasStyle *style = item->simple_data->style;
 
1793
  gboolean do_fill, do_stroke;
 
1794
 
 
1795
  /* Check the filled path, if required. */
 
1796
  if (pointer_events & GOO_CANVAS_EVENTS_FILL_MASK)
 
1797
    {
 
1798
      do_fill = goo_canvas_style_set_fill_options (style, cr);
 
1799
      if (!(pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK) || do_fill)
 
1800
        {
 
1801
          if (cairo_in_fill (cr, x, y))
 
1802
            return TRUE;
 
1803
        }
 
1804
    }
 
1805
 
 
1806
  /* Check the stroke, if required. */
 
1807
  if (pointer_events & GOO_CANVAS_EVENTS_STROKE_MASK)
 
1808
    {
 
1809
      do_stroke = goo_canvas_style_set_stroke_options (style, cr);
 
1810
      if (!(pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK) || do_stroke)
 
1811
        {
 
1812
          if (cairo_in_stroke (cr, x, y))
 
1813
            return TRUE;
 
1814
        }
 
1815
    }
 
1816
 
 
1817
  return FALSE;
 
1818
}
 
1819
 
 
1820
 
 
1821
/**
 
1822
 * goo_canvas_item_simple_get_line_width:
 
1823
 * @item: a #GooCanvasItemSimple.
 
1824
 * 
 
1825
 * Gets the item's line width.
 
1826
 * 
 
1827
 * Returns: the item's line width.
 
1828
 **/
 
1829
gdouble
 
1830
goo_canvas_item_simple_get_line_width (GooCanvasItemSimple   *item)
 
1831
{
 
1832
  GValue *value;
 
1833
 
 
1834
  value = goo_canvas_style_get_property (item->simple_data->style,
 
1835
                                         goo_canvas_style_line_width_id);
 
1836
  if (value)
 
1837
    return value->data[0].v_double;
 
1838
  else if (item->canvas)
 
1839
    return goo_canvas_get_default_line_width (item->canvas);
 
1840
  else
 
1841
    return 2.0;
 
1842
}
 
1843
 
 
1844
 
 
1845
/**
 
1846
 * SECTION:goocanvasitemmodelsimple
 
1847
 * @Title: GooCanvasItemModelSimple
 
1848
 * @Short_Description: the base class for the standard canvas item models.
 
1849
 * @Stability_Level: 
 
1850
 * @See_Also: 
 
1851
 *
 
1852
 * #GooCanvasItemModelSimple is used as a base class for the standard canvas
 
1853
 * item models. It can also be used as the base class for new custom canvas
 
1854
 * item models.
 
1855
 *
 
1856
 * It provides default implementations for many of the #GooCanvasItemModel
 
1857
 * methods.
 
1858
 *
 
1859
 * Subclasses of #GooCanvasItemModelSimple only need to implement the
 
1860
 * create_item() method of the #GooCanvasItemModel interface, to create
 
1861
 * the default canvas item to view the item model.
 
1862
 */
 
1863
 
 
1864
 
 
1865
static void item_model_interface_init  (GooCanvasItemModelIface *iface);
 
1866
static void goo_canvas_item_model_simple_dispose  (GObject *object);
 
1867
static void goo_canvas_item_model_simple_finalize (GObject *object);
 
1868
static void goo_canvas_item_model_simple_get_property (GObject              *object,
 
1869
                                                       guint                 prop_id,
 
1870
                                                       GValue               *value,
 
1871
                                                       GParamSpec           *pspec);
 
1872
static void goo_canvas_item_model_simple_set_property (GObject              *object,
 
1873
                                                       guint                 prop_id,
 
1874
                                                       const GValue         *value,
 
1875
                                                       GParamSpec           *pspec);
 
1876
 
 
1877
G_DEFINE_TYPE_WITH_CODE (GooCanvasItemModelSimple,
 
1878
                         goo_canvas_item_model_simple, G_TYPE_OBJECT,
 
1879
                         G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
 
1880
                                                item_model_interface_init))
 
1881
 
 
1882
 
 
1883
static void
 
1884
goo_canvas_item_model_simple_class_init (GooCanvasItemModelSimpleClass *klass)
 
1885
{
 
1886
  GObjectClass *gobject_class = (GObjectClass*) klass;
 
1887
 
 
1888
  gobject_class->dispose  = goo_canvas_item_model_simple_dispose;
 
1889
  gobject_class->finalize = goo_canvas_item_model_simple_finalize;
 
1890
 
 
1891
  gobject_class->get_property = goo_canvas_item_model_simple_get_property;
 
1892
  gobject_class->set_property = goo_canvas_item_model_simple_set_property;
 
1893
 
 
1894
  goo_canvas_item_simple_install_common_properties (gobject_class);
 
1895
}
 
1896
 
 
1897
 
 
1898
static void
 
1899
goo_canvas_item_model_simple_init (GooCanvasItemModelSimple *smodel)
 
1900
{
 
1901
  smodel->simple_data.visibility = GOO_CANVAS_ITEM_VISIBLE;
 
1902
  smodel->simple_data.pointer_events = GOO_CANVAS_EVENTS_VISIBLE_PAINTED;
 
1903
  smodel->simple_data.clip_fill_rule = CAIRO_FILL_RULE_WINDING;
 
1904
}
 
1905
 
 
1906
 
 
1907
static void
 
1908
goo_canvas_item_model_simple_dispose (GObject *object)
 
1909
{
 
1910
  GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) object;
 
1911
 
 
1912
  goo_canvas_item_simple_free_data (&smodel->simple_data);
 
1913
 
 
1914
  G_OBJECT_CLASS (goo_canvas_item_model_simple_parent_class)->dispose (object);
 
1915
}
 
1916
 
 
1917
 
 
1918
static void
 
1919
goo_canvas_item_model_simple_finalize (GObject *object)
 
1920
{
 
1921
  /*GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) object;*/
 
1922
 
 
1923
  G_OBJECT_CLASS (goo_canvas_item_model_simple_parent_class)->finalize (object);
 
1924
}
 
1925
 
 
1926
 
 
1927
static void
 
1928
goo_canvas_item_model_simple_get_property (GObject              *object,
 
1929
                                           guint                 prop_id,
 
1930
                                           GValue               *value,
 
1931
                                           GParamSpec           *pspec)
 
1932
{
 
1933
  GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) object;
 
1934
  GooCanvasItemSimpleData *simple_data = &smodel->simple_data;
 
1935
 
 
1936
  switch (prop_id)
 
1937
    {
 
1938
    case PROP_PARENT:
 
1939
      g_value_set_object (value, smodel->parent);
 
1940
      break;
 
1941
    case PROP_TITLE:
 
1942
      g_value_set_string (value, smodel->title);
 
1943
      break;
 
1944
    case PROP_DESCRIPTION:
 
1945
      g_value_set_string (value, smodel->description);
 
1946
      break;
 
1947
    default:
 
1948
      goo_canvas_item_simple_get_common_property (object, simple_data, NULL,
 
1949
                                                  prop_id, value, pspec);
 
1950
      break;
 
1951
    }
 
1952
}
 
1953
 
 
1954
 
 
1955
extern void _goo_canvas_item_model_emit_changed (GooCanvasItemModel *model,
 
1956
                                                 gboolean            recompute_bounds);
 
1957
 
 
1958
static void
 
1959
goo_canvas_item_model_simple_set_property (GObject              *object,
 
1960
                                           guint                 prop_id,
 
1961
                                           const GValue         *value,
 
1962
                                           GParamSpec           *pspec)
 
1963
{
 
1964
  GooCanvasItemModel *model = (GooCanvasItemModel*) object;
 
1965
  GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) object;
 
1966
  GooCanvasItemSimpleData *simple_data = &smodel->simple_data;
 
1967
  GooCanvasItemModel *parent;
 
1968
  gboolean recompute_bounds;
 
1969
 
 
1970
  switch (prop_id)
 
1971
    {
 
1972
    case PROP_PARENT:
 
1973
      parent = g_value_get_object (value);
 
1974
      goo_canvas_item_model_remove (model);
 
1975
      goo_canvas_item_model_add_child (parent, model, -1);
 
1976
      break;
 
1977
    case PROP_TITLE:
 
1978
      g_free (smodel->title);
 
1979
      smodel->title = g_value_dup_string (value);
 
1980
      break;
 
1981
    case PROP_DESCRIPTION:
 
1982
      g_free (smodel->description);
 
1983
      smodel->description = g_value_dup_string (value);
 
1984
      break;
 
1985
    default:
 
1986
      recompute_bounds = goo_canvas_item_simple_set_common_property (object,
 
1987
                                                                     simple_data,
 
1988
                                                                     prop_id,
 
1989
                                                                     value,
 
1990
                                                                     pspec);
 
1991
      _goo_canvas_item_model_emit_changed (model, recompute_bounds);
 
1992
      break;
 
1993
    }
 
1994
}
 
1995
 
 
1996
 
 
1997
static GooCanvasItemModel*
 
1998
goo_canvas_item_model_simple_get_parent (GooCanvasItemModel   *model)
 
1999
{
 
2000
  GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) model;
 
2001
  return smodel->parent;
 
2002
}
 
2003
 
 
2004
 
 
2005
static void
 
2006
goo_canvas_item_model_simple_set_parent (GooCanvasItemModel   *model,
 
2007
                                         GooCanvasItemModel   *parent)
 
2008
{
 
2009
  GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) model;
 
2010
  smodel->parent = parent;
 
2011
}
 
2012
 
 
2013
 
 
2014
static gboolean
 
2015
goo_canvas_item_model_simple_get_transform (GooCanvasItemModel  *model,
 
2016
                                            cairo_matrix_t      *matrix)
 
2017
{
 
2018
  GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) model;
 
2019
  GooCanvasItemSimpleData *simple_data = &smodel->simple_data;
 
2020
 
 
2021
  if (!simple_data->transform)
 
2022
    return FALSE;
 
2023
 
 
2024
  *matrix = *simple_data->transform;
 
2025
  return TRUE;
 
2026
}
 
2027
 
 
2028
 
 
2029
static void
 
2030
goo_canvas_item_model_simple_set_transform (GooCanvasItemModel   *model,
 
2031
                                            const cairo_matrix_t *transform)
 
2032
{
 
2033
  GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) model;
 
2034
  GooCanvasItemSimpleData *simple_data = &smodel->simple_data;
 
2035
 
 
2036
  if (transform)
 
2037
    {
 
2038
      if (!simple_data->transform)
 
2039
        simple_data->transform = g_slice_new (cairo_matrix_t);
 
2040
 
 
2041
      *simple_data->transform = *transform;
 
2042
    }
 
2043
  else
 
2044
    {
 
2045
      g_slice_free (cairo_matrix_t, simple_data->transform);
 
2046
      simple_data->transform = NULL;
 
2047
    }
 
2048
 
 
2049
  _goo_canvas_item_model_emit_changed (model, TRUE);
 
2050
}
 
2051
 
 
2052
 
 
2053
static GooCanvasStyle*
 
2054
goo_canvas_item_model_simple_get_style (GooCanvasItemModel  *model)
 
2055
{
 
2056
  GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) model;
 
2057
 
 
2058
  return smodel->simple_data.style;
 
2059
}
 
2060
 
 
2061
 
 
2062
static void
 
2063
goo_canvas_item_model_simple_set_style (GooCanvasItemModel *model,
 
2064
                                        GooCanvasStyle     *style)
 
2065
{
 
2066
  GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) model;
 
2067
  GooCanvasItemSimpleData *simple_data = &smodel->simple_data;
 
2068
 
 
2069
  if (simple_data->style)
 
2070
    g_object_unref (simple_data->style);
 
2071
 
 
2072
  if (style)
 
2073
    {
 
2074
      simple_data->style = goo_canvas_style_copy (style);
 
2075
      simple_data->own_style = TRUE;
 
2076
    }
 
2077
  else
 
2078
    {
 
2079
      simple_data->style = NULL;
 
2080
      simple_data->own_style = FALSE;
 
2081
    }
 
2082
 
 
2083
  _goo_canvas_item_model_emit_changed (model, TRUE);
 
2084
}
 
2085
 
 
2086
 
 
2087
static void
 
2088
item_model_interface_init  (GooCanvasItemModelIface *iface)
 
2089
{
 
2090
  iface->get_parent     = goo_canvas_item_model_simple_get_parent;
 
2091
  iface->set_parent     = goo_canvas_item_model_simple_set_parent;
 
2092
  iface->get_transform  = goo_canvas_item_model_simple_get_transform;
 
2093
  iface->set_transform  = goo_canvas_item_model_simple_set_transform;
 
2094
  iface->get_style      = goo_canvas_item_model_simple_get_style;
 
2095
  iface->set_style      = goo_canvas_item_model_simple_set_style;
 
2096
}