From 56b9c4f4c887c18d2be1a2dd752ab73ead65ba6d Mon Sep 17 00:00:00 2001 From: Bruno Coudoin Date: Sun, 08 Nov 2009 15:16:26 +0000 Subject: Updated with upstream goocanvas 0.15 and pygoocanvas 0.14.1. (I patched pygoocanvas to make it compile with goocanvas 0.15). --- diff --git a/src/boards/goocanvas.c b/src/boards/goocanvas.c index f94b5be..7136d93 100644 --- a/src/boards/goocanvas.c +++ b/src/boards/goocanvas.c @@ -207,6 +207,8 @@ static PyTypeObject *_PyGtkContainer_Type; #define PyGtkContainer_Type (*_PyGtkContainer_Type) static PyTypeObject *_PyGtkAdjustment_Type; #define PyGtkAdjustment_Type (*_PyGtkAdjustment_Type) +static PyTypeObject *_PyGdkCairoContext_Type; +#define PyGdkCairoContext_Type (*_PyGdkCairoContext_Type) /* ---------- forward type declarations ---------- */ @@ -219,7 +221,6 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasGroupModel_Type; PyTypeObject G_GNUC_INTERNAL PyGooCanvasEllipseModel_Type; PyTypeObject G_GNUC_INTERNAL PyGooCanvasItemSimple_Type; PyTypeObject G_GNUC_INTERNAL PyGooCanvasImage_Type; -PyTypeObject G_GNUC_INTERNAL PyGooCanvasSvg_Type; PyTypeObject G_GNUC_INTERNAL PyGooCanvasGroup_Type; PyTypeObject G_GNUC_INTERNAL PyGooCanvasEllipse_Type; PyTypeObject G_GNUC_INTERNAL PyGooCanvasPath_Type; @@ -238,7 +239,7 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasItem_Type; PyTypeObject G_GNUC_INTERNAL PyGooCanvasItemModel_Type; -#line 664 "goocanvas.override" +#line 667 "goocanvas.override" static PyObject * _py_canvas_style_get_property(GooCanvasStyle *style, @@ -289,13 +290,13 @@ _py_goo_canvas_style_set_property(GooCanvasStyle *style, } -#line 293 "goocanvas.c" +#line 296 "goocanvas.c" /* ----------- GooCanvasPoints ----------- */ -#line 280 "goocanvas.override" +#line 283 "goocanvas.override" static int _wrap_goo_canvas_points_new(PyGBoxed *self, PyObject *args, PyObject *kwargs) { @@ -322,9 +323,52 @@ _wrap_goo_canvas_points_new(PyGBoxed *self, PyObject *args, PyObject *kwargs) self->gtype = GOO_TYPE_CANVAS_POINTS; return 0; } -#line 326 "goocanvas.c" +#line 329 "goocanvas.c" +#line 1883 "goocanvas.override" + +static PyObject * +_wrap_goo_canvas_points__get_coords(PyObject *self, void *closure) +{ + gdouble *coords; + int num_points, i; + PyObject *ret = Py_None; + + num_points = pyg_boxed_get(self, GooCanvasPoints)->num_points; + coords = pyg_boxed_get(self, GooCanvasPoints)->coords; + + if (num_points > 0) { + ret = PyList_New(num_points); + + for (i = 0; i < num_points; i ++) { + PyObject *py_temp = Py_BuildValue("dd", coords[2*i], coords[2*i + 1]); + PyList_SetItem(ret, i, py_temp); + } + return ret; + } + Py_INCREF(ret); + return ret; +} + +#line 357 "goocanvas.c" + + +static PyObject * +_wrap_goo_canvas_points__get_num_points(PyObject *self, void *closure) +{ + int ret; + + ret = pyg_boxed_get(self, GooCanvasPoints)->num_points; + return PyInt_FromLong(ret); +} + +static const PyGetSetDef goo_canvas_points_getsets[] = { + { "coords", (getter)_wrap_goo_canvas_points__get_coords, (setter)0 }, + { "num_points", (getter)_wrap_goo_canvas_points__get_num_points, (setter)0 }, + { NULL, (getter)0, (setter)0 }, +}; + PyTypeObject G_GNUC_INTERNAL PyGooCanvasPoints_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ @@ -357,7 +401,7 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasPoints_Type = { (iternextfunc)0, /* tp_iternext */ (struct PyMethodDef*)NULL, /* tp_methods */ (struct PyMemberDef*)0, /* tp_members */ - (struct PyGetSetDef*)0, /* tp_getset */ + (struct PyGetSetDef*)goo_canvas_points_getsets, /* tp_getset */ NULL, /* tp_base */ NULL, /* tp_dict */ (descrgetfunc)0, /* tp_descr_get */ @@ -374,7 +418,7 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasPoints_Type = { /* ----------- GooCanvasLineDash ----------- */ -#line 445 "goocanvas.override" +#line 448 "goocanvas.override" static int _wrap_goo_canvas_line_dash_newv(PyGBoxed *self, PyObject *args, PyObject *kwargs) { @@ -411,7 +455,7 @@ _wrap_goo_canvas_line_dash_newv(PyGBoxed *self, PyObject *args, PyObject *kwargs self->free_on_dealloc = TRUE; return 0; } -#line 415 "goocanvas.c" +#line 461 "goocanvas.c" PyTypeObject G_GNUC_INTERNAL PyGooCanvasLineDash_Type = { @@ -463,34 +507,14 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasLineDash_Type = { /* ----------- GooCanvas ----------- */ -static int -_wrap_goo_canvas_new(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char* kwlist[] = { NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - ":goocanvas.Canvas.__init__", - kwlist)) - return -1; - - pygobject_constructv(self, 0, NULL); - if (!self->obj) { - PyErr_SetString( - PyExc_RuntimeError, - "could not create goocanvas.Canvas object"); - return -1; - } - return 0; -} - static PyObject * _wrap_goo_canvas_get_root_item(PyGObject *self) { GooCanvasItem *ret; - + ret = goo_canvas_get_root_item(GOO_CANVAS(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -503,9 +527,9 @@ _wrap_goo_canvas_set_root_item(PyGObject *self, PyObject *args, PyObject *kwargs if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.set_root_item", kwlist, &PyGooCanvasItem_Type, &item)) return NULL; - + goo_canvas_set_root_item(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM(item->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -515,9 +539,9 @@ _wrap_goo_canvas_get_root_item_model(PyGObject *self) { GooCanvasItemModel *ret; - + ret = goo_canvas_get_root_item_model(GOO_CANVAS(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -530,9 +554,63 @@ _wrap_goo_canvas_set_root_item_model(PyGObject *self, PyObject *args, PyObject * if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.set_root_item_model", kwlist, &PyGooCanvasItemModel_Type, &model)) return NULL; - + goo_canvas_set_root_item_model(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM_MODEL(model->obj)); - + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_goo_canvas_get_static_root_item(PyGObject *self) +{ + GooCanvasItem *ret; + + + ret = goo_canvas_get_static_root_item(GOO_CANVAS(self->obj)); + + /* pygobject_new handles NULL checking */ + return pygobject_new((GObject *)ret); +} + +static PyObject * +_wrap_goo_canvas_set_static_root_item(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "item", NULL }; + PyGObject *item; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.set_static_root_item", kwlist, &PyGooCanvasItem_Type, &item)) + return NULL; + + goo_canvas_set_static_root_item(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM(item->obj)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_goo_canvas_get_static_root_item_model(PyGObject *self) +{ + GooCanvasItemModel *ret; + + + ret = goo_canvas_get_static_root_item_model(GOO_CANVAS(self->obj)); + + /* pygobject_new handles NULL checking */ + return pygobject_new((GObject *)ret); +} + +static PyObject * +_wrap_goo_canvas_set_static_root_item_model(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "model", NULL }; + PyGObject *model; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.set_static_root_item_model", kwlist, &PyGooCanvasItemModel_Type, &model)) + return NULL; + + goo_canvas_set_static_root_item_model(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM_MODEL(model->obj)); + Py_INCREF(Py_None); return Py_None; } @@ -546,9 +624,9 @@ _wrap_goo_canvas_get_item(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.get_item", kwlist, &PyGooCanvasItemModel_Type, &model)) return NULL; - + ret = goo_canvas_get_item(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM_MODEL(model->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -563,14 +641,14 @@ _wrap_goo_canvas_get_item_at(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"ddi:GooCanvas.get_item_at", kwlist, &x, &y, &is_pointer_event)) return NULL; - + ret = goo_canvas_get_item_at(GOO_CANVAS(self->obj), x, y, is_pointer_event); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } -#line 1437 "goocanvas.override" +#line 1440 "goocanvas.override" static PyObject * _wrap_goo_canvas_get_items_at(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -601,10 +679,10 @@ _wrap_goo_canvas_get_items_at(PyGObject *self, PyObject *args, PyObject *kwargs) return ret; } -#line 605 "goocanvas.c" +#line 685 "goocanvas.c" -#line 1469 "goocanvas.override" +#line 1472 "goocanvas.override" static PyObject * _wrap_goo_canvas_get_items_in_area(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -642,7 +720,7 @@ _wrap_goo_canvas_get_items_in_area(PyGObject *self, PyObject *args, PyObject *kw return ret; } -#line 646 "goocanvas.c" +#line 726 "goocanvas.c" static PyObject * @@ -650,9 +728,9 @@ _wrap_goo_canvas_get_scale(PyGObject *self) { double ret; - + ret = goo_canvas_get_scale(GOO_CANVAS(self->obj)); - + return PyFloat_FromDouble(ret); } @@ -664,14 +742,14 @@ _wrap_goo_canvas_set_scale(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"d:GooCanvas.set_scale", kwlist, &pixels_per_unit)) return NULL; - + goo_canvas_set_scale(GOO_CANVAS(self->obj), pixels_per_unit); - + Py_INCREF(Py_None); return Py_None; } -#line 513 "goocanvas.override" +#line 516 "goocanvas.override" static PyObject * _wrap_goo_canvas_get_bounds(PyGObject *self) { @@ -682,7 +760,7 @@ _wrap_goo_canvas_get_bounds(PyGObject *self) return Py_BuildValue("dddd", left, right, top, bottom); } -#line 686 "goocanvas.c" +#line 766 "goocanvas.c" static PyObject * @@ -693,9 +771,9 @@ _wrap_goo_canvas_set_bounds(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"dddd:GooCanvas.set_bounds", kwlist, &left, &top, &right, &bottom)) return NULL; - + goo_canvas_set_bounds(GOO_CANVAS(self->obj), left, top, right, bottom); - + Py_INCREF(Py_None); return Py_None; } @@ -708,9 +786,9 @@ _wrap_goo_canvas_scroll_to(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"dd:GooCanvas.scroll_to", kwlist, &left, &top)) return NULL; - + goo_canvas_scroll_to(GOO_CANVAS(self->obj), left, top); - + Py_INCREF(Py_None); return Py_None; } @@ -723,9 +801,9 @@ _wrap_goo_canvas_grab_focus(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.grab_focus", kwlist, &PyGooCanvasItem_Type, &item)) return NULL; - + goo_canvas_grab_focus(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM(item->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -740,19 +818,19 @@ _wrap_goo_canvas_render(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!|Od:GooCanvas.render", kwlist, &PycairoContext_Type, &cr, &py_bounds, &scale)) return NULL; - if (!(py_bounds == NULL || py_bounds == Py_None || + if (!(py_bounds == NULL || py_bounds == Py_None || PyObject_IsInstance(py_bounds, (PyObject *) &PyGooCanvasBounds_Type))) { PyErr_SetString(PyExc_TypeError, "parameter bounds must be goocanvas.Bounds or None"); return NULL; } - + goo_canvas_render(GOO_CANVAS(self->obj), cr->ctx, (py_bounds == NULL || py_bounds == Py_None)? NULL : &((PyGooCanvasBounds *) py_bounds)->bounds, scale); - + Py_INCREF(Py_None); return Py_None; } -#line 540 "goocanvas.override" +#line 543 "goocanvas.override" static PyObject * _wrap_goo_canvas_convert_to_pixels(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -767,10 +845,10 @@ _wrap_goo_canvas_convert_to_pixels(PyGObject *self, PyObject *args, PyObject *kw return Py_BuildValue("dd", x, y); } -#line 771 "goocanvas.c" +#line 851 "goocanvas.c" -#line 556 "goocanvas.override" +#line 559 "goocanvas.override" static PyObject * _wrap_goo_canvas_convert_from_pixels(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -785,10 +863,10 @@ _wrap_goo_canvas_convert_from_pixels(PyGObject *self, PyObject *args, PyObject * return Py_BuildValue("dd", x, y); } -#line 789 "goocanvas.c" +#line 869 "goocanvas.c" -#line 572 "goocanvas.override" +#line 575 "goocanvas.override" static PyObject * _wrap_goo_canvas_convert_to_item_space(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -804,10 +882,10 @@ _wrap_goo_canvas_convert_to_item_space(PyGObject *self, PyObject *args, PyObject return Py_BuildValue("dd", x, y); } -#line 808 "goocanvas.c" +#line 888 "goocanvas.c" -#line 589 "goocanvas.override" +#line 592 "goocanvas.override" static PyObject * _wrap_goo_canvas_convert_from_item_space(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -823,10 +901,26 @@ _wrap_goo_canvas_convert_from_item_space(PyGObject *self, PyObject *args, PyObje return Py_BuildValue("dd", x, y); } -#line 827 "goocanvas.c" +#line 907 "goocanvas.c" static PyObject * +_wrap_goo_canvas_convert_bounds_to_item_space(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "item", "bounds", NULL }; + PyGObject *item; + PyObject *py_bounds; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O!:GooCanvas.convert_bounds_to_item_space", kwlist, &PyGooCanvasItem_Type, &item, &PyGooCanvasBounds_Type, &py_bounds)) + return NULL; + + goo_canvas_convert_bounds_to_item_space(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM(item->obj), (py_bounds == NULL)? NULL : &((PyGooCanvasBounds *) py_bounds)->bounds); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * _wrap_goo_canvas_pointer_grab(PyGObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "item", "event_mask", "cursor", "time", NULL }; @@ -847,9 +941,9 @@ _wrap_goo_canvas_pointer_grab(PyGObject *self, PyObject *args, PyObject *kwargs) PyErr_SetString(PyExc_TypeError, "cursor should be a GdkCursor or None"); return NULL; } - + ret = goo_canvas_pointer_grab(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM(item->obj), event_mask, cursor, time); - + return pyg_enum_from_gtype(GDK_TYPE_GRAB_STATUS, ret); } @@ -862,9 +956,9 @@ _wrap_goo_canvas_pointer_ungrab(PyGObject *self, PyObject *args, PyObject *kwarg if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!k:GooCanvas.pointer_ungrab", kwlist, &PyGooCanvasItem_Type, &item, &time)) return NULL; - + goo_canvas_pointer_ungrab(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM(item->obj), time); - + Py_INCREF(Py_None); return Py_None; } @@ -880,9 +974,9 @@ _wrap_goo_canvas_keyboard_grab(PyGObject *self, PyObject *args, PyObject *kwargs if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!ik:GooCanvas.keyboard_grab", kwlist, &PyGooCanvasItem_Type, &item, &owner_events, &time)) return NULL; - + ret = goo_canvas_keyboard_grab(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM(item->obj), owner_events, time); - + return pyg_enum_from_gtype(GDK_TYPE_GRAB_STATUS, ret); } @@ -895,24 +989,26 @@ _wrap_goo_canvas_keyboard_ungrab(PyGObject *self, PyObject *args, PyObject *kwar if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!k:GooCanvas.keyboard_ungrab", kwlist, &PyGooCanvasItem_Type, &item, &time)) return NULL; - + goo_canvas_keyboard_ungrab(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM(item->obj), time); - + Py_INCREF(Py_None); return Py_None; } +#line 2032 "goocanvas.override" static PyObject * _wrap_goo_canvas_create_cairo_context(PyGObject *self) { cairo_t *ret; - ret = goo_canvas_create_cairo_context(GOO_CANVAS(self->obj)); - + cairo_reference(ret); - return PycairoContext_FromContext(ret, NULL, NULL); + return PycairoContext_FromContext(ret, &PyGdkCairoContext_Type, NULL); } +#line 1013 "goocanvas.c" + static PyObject * _wrap_goo_canvas_create_item(PyGObject *self, PyObject *args, PyObject *kwargs) @@ -923,9 +1019,9 @@ _wrap_goo_canvas_create_item(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.create_item", kwlist, &PyGooCanvasItemModel_Type, &model)) return NULL; - + ret = goo_canvas_create_item(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM_MODEL(model->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -938,9 +1034,9 @@ _wrap_goo_canvas_unregister_item(PyGObject *self, PyObject *args, PyObject *kwar if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.unregister_item", kwlist, &PyGooCanvasItemModel_Type, &model)) return NULL; - + goo_canvas_unregister_item(GOO_CANVAS(self->obj), GOO_CANVAS_ITEM_MODEL(model->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -948,9 +1044,9 @@ _wrap_goo_canvas_unregister_item(PyGObject *self, PyObject *args, PyObject *kwar static PyObject * _wrap_goo_canvas_update(PyGObject *self) { - + goo_canvas_update(GOO_CANVAS(self->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -958,9 +1054,9 @@ _wrap_goo_canvas_update(PyGObject *self) static PyObject * _wrap_goo_canvas_request_update(PyGObject *self) { - + goo_canvas_request_update(GOO_CANVAS(self->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -973,9 +1069,25 @@ _wrap_goo_canvas_request_redraw(PyGObject *self, PyObject *args, PyObject *kwarg if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.request_redraw", kwlist, &PyGooCanvasBounds_Type, &py_bounds)) return NULL; - + goo_canvas_request_redraw(GOO_CANVAS(self->obj), (py_bounds == NULL)? NULL : &((PyGooCanvasBounds *) py_bounds)->bounds); - + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_goo_canvas_request_item_redraw(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "bounds", "is_static", NULL }; + PyObject *py_bounds; + int is_static; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!i:GooCanvas.request_item_redraw", kwlist, &PyGooCanvasBounds_Type, &py_bounds, &is_static)) + return NULL; + + goo_canvas_request_item_redraw(GOO_CANVAS(self->obj), (py_bounds == NULL)? NULL : &((PyGooCanvasBounds *) py_bounds)->bounds, is_static); + Py_INCREF(Py_None); return Py_None; } @@ -985,9 +1097,9 @@ _wrap_goo_canvas_get_default_line_width(PyGObject *self) { double ret; - + ret = goo_canvas_get_default_line_width(GOO_CANVAS(self->obj)); - + return PyFloat_FromDouble(ret); } @@ -999,9 +1111,9 @@ _wrap_goo_canvas_register_widget_item(PyGObject *self, PyObject *args, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.register_widget_item", kwlist, &PyGooCanvasWidget_Type, &witem)) return NULL; - + goo_canvas_register_widget_item(GOO_CANVAS(self->obj), GOO_CANVAS_WIDGET(witem->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -1014,9 +1126,9 @@ _wrap_goo_canvas_unregister_widget_item(PyGObject *self, PyObject *args, PyObjec if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvas.unregister_widget_item", kwlist, &PyGooCanvasWidget_Type, &witem)) return NULL; - + goo_canvas_unregister_widget_item(GOO_CANVAS(self->obj), GOO_CANVAS_WIDGET(witem->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -1097,6 +1209,14 @@ static const PyMethodDef _PyGooCanvas_methods[] = { NULL }, { "set_root_item_model", (PyCFunction)_wrap_goo_canvas_set_root_item_model, METH_VARARGS|METH_KEYWORDS, NULL }, + { "get_static_root_item", (PyCFunction)_wrap_goo_canvas_get_static_root_item, METH_NOARGS, + NULL }, + { "set_static_root_item", (PyCFunction)_wrap_goo_canvas_set_static_root_item, METH_VARARGS|METH_KEYWORDS, + NULL }, + { "get_static_root_item_model", (PyCFunction)_wrap_goo_canvas_get_static_root_item_model, METH_NOARGS, + NULL }, + { "set_static_root_item_model", (PyCFunction)_wrap_goo_canvas_set_static_root_item_model, METH_VARARGS|METH_KEYWORDS, + NULL }, { "get_item", (PyCFunction)_wrap_goo_canvas_get_item, METH_VARARGS|METH_KEYWORDS, NULL }, { "get_item_at", (PyCFunction)_wrap_goo_canvas_get_item_at, METH_VARARGS|METH_KEYWORDS, @@ -1127,6 +1247,8 @@ static const PyMethodDef _PyGooCanvas_methods[] = { NULL }, { "convert_from_item_space", (PyCFunction)_wrap_goo_canvas_convert_from_item_space, METH_VARARGS|METH_KEYWORDS, NULL }, + { "convert_bounds_to_item_space", (PyCFunction)_wrap_goo_canvas_convert_bounds_to_item_space, METH_VARARGS|METH_KEYWORDS, + NULL }, { "pointer_grab", (PyCFunction)_wrap_goo_canvas_pointer_grab, METH_VARARGS|METH_KEYWORDS, NULL }, { "pointer_ungrab", (PyCFunction)_wrap_goo_canvas_pointer_ungrab, METH_VARARGS|METH_KEYWORDS, @@ -1147,6 +1269,8 @@ static const PyMethodDef _PyGooCanvas_methods[] = { NULL }, { "request_redraw", (PyCFunction)_wrap_goo_canvas_request_redraw, METH_VARARGS|METH_KEYWORDS, NULL }, + { "request_item_redraw", (PyCFunction)_wrap_goo_canvas_request_item_redraw, METH_VARARGS|METH_KEYWORDS, + NULL }, { "get_default_line_width", (PyCFunction)_wrap_goo_canvas_get_default_line_width, METH_NOARGS, NULL }, { "register_widget_item", (PyCFunction)_wrap_goo_canvas_register_widget_item, METH_VARARGS|METH_KEYWORDS, @@ -1200,7 +1324,7 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvas_Type = { (descrgetfunc)0, /* tp_descr_get */ (descrsetfunc)0, /* tp_descr_set */ offsetof(PyGObject, inst_dict), /* tp_dictoffset */ - (initproc)_wrap_goo_canvas_new, /* tp_init */ + (initproc)0, /* tp_init */ (allocfunc)0, /* tp_alloc */ (newfunc)0, /* tp_new */ (freefunc)0, /* tp_free */ @@ -1217,7 +1341,7 @@ _wrap_GooCanvas__proxy_do_set_scroll_adjustments(GooCanvas *self, GtkAdjustment* PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -1238,11 +1362,11 @@ _wrap_GooCanvas__proxy_do_set_scroll_adjustments(GooCanvas *self, GtkAdjustment* Py_INCREF(Py_None); py_vadjustment = Py_None; } - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_hadjustment); PyTuple_SET_ITEM(py_args, 1, py_vadjustment); - + py_method = PyObject_GetAttrString(py_self, "do_set_scroll_adjustments"); if (!py_method) { if (PyErr_Occurred()) @@ -1273,8 +1397,8 @@ _wrap_GooCanvas__proxy_do_set_scroll_adjustments(GooCanvas *self, GtkAdjustment* pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -1291,7 +1415,7 @@ _wrap_GooCanvas__proxy_do_create_item(GooCanvas *self, GooCanvasItemModel*model) PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -1306,10 +1430,10 @@ _wrap_GooCanvas__proxy_do_create_item(GooCanvas *self, GooCanvasItemModel*model) Py_INCREF(Py_None); py_model = Py_None; } - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_model); - + py_method = PyObject_GetAttrString(py_self, "do_create_item"); if (!py_method) { if (PyErr_Occurred()) @@ -1352,14 +1476,14 @@ _wrap_GooCanvas__proxy_do_create_item(GooCanvas *self, GooCanvasItemModel*model) } retval = (GooCanvasItem*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -1372,7 +1496,7 @@ _wrap_GooCanvas__proxy_do_item_created(GooCanvas *self, GooCanvasItem*item, GooC PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -1393,11 +1517,11 @@ _wrap_GooCanvas__proxy_do_item_created(GooCanvas *self, GooCanvasItem*item, GooC Py_INCREF(Py_None); py_model = Py_None; } - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_item); PyTuple_SET_ITEM(py_args, 1, py_model); - + py_method = PyObject_GetAttrString(py_self, "do_item_created"); if (!py_method) { if (PyErr_Occurred()) @@ -1428,8 +1552,8 @@ _wrap_GooCanvas__proxy_do_item_created(GooCanvas *self, GooCanvasItem*item, GooC pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -1525,7 +1649,6 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasItemModelSimple_Type = { }; - /* ----------- GooCanvasImageModel ----------- */ PyTypeObject G_GNUC_INTERNAL PyGooCanvasImageModel_Type = { @@ -1675,7 +1798,7 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasEllipseModel_Type = { /* ----------- GooCanvasItemSimple ----------- */ -#line 257 "goocanvas.override" +#line 260 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_simple_get_path_bounds(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -1697,7 +1820,7 @@ _wrap_goo_canvas_item_simple_get_path_bounds(PyGObject *self, PyObject *args, Py return py_bounds; } -#line 1701 "goocanvas.c" +#line 1876 "goocanvas.c" static PyObject * @@ -1709,9 +1832,9 @@ _wrap_goo_canvas_item_simple_user_bounds_to_device(PyGObject *self, PyObject *ar if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O!:GooCanvasItemSimple.user_bounds_to_device", kwlist, &PycairoContext_Type, &cr, &PyGooCanvasBounds_Type, &py_bounds)) return NULL; - + goo_canvas_item_simple_user_bounds_to_device(GOO_CANVAS_ITEM_SIMPLE(self->obj), cr->ctx, (py_bounds == NULL)? NULL : &((PyGooCanvasBounds *) py_bounds)->bounds); - + Py_INCREF(Py_None); return Py_None; } @@ -1725,9 +1848,9 @@ _wrap_goo_canvas_item_simple_user_bounds_to_parent(PyGObject *self, PyObject *ar if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O!:GooCanvasItemSimple.user_bounds_to_parent", kwlist, &PycairoContext_Type, &cr, &PyGooCanvasBounds_Type, &py_bounds)) return NULL; - + goo_canvas_item_simple_user_bounds_to_parent(GOO_CANVAS_ITEM_SIMPLE(self->obj), cr->ctx, (py_bounds == NULL)? NULL : &((PyGooCanvasBounds *) py_bounds)->bounds); - + Py_INCREF(Py_None); return Py_None; } @@ -1746,9 +1869,9 @@ _wrap_goo_canvas_item_simple_check_in_path(PyGObject *self, PyObject *args, PyOb return NULL; if (pyg_flags_get_value(GOO_TYPE_CANVAS_POINTER_EVENTS, py_pointer_events, (gpointer)&pointer_events)) return NULL; - + ret = goo_canvas_item_simple_check_in_path(GOO_CANVAS_ITEM_SIMPLE(self->obj), x, y, cr->ctx, pointer_events); - + return PyBool_FromLong(ret); } @@ -1761,9 +1884,9 @@ _wrap_goo_canvas_item_simple_paint_path(PyGObject *self, PyObject *args, PyObjec if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItemSimple.paint_path", kwlist, &PycairoContext_Type, &cr)) return NULL; - + goo_canvas_item_simple_paint_path(GOO_CANVAS_ITEM_SIMPLE(self->obj), cr->ctx); - + Py_INCREF(Py_None); return Py_None; } @@ -1776,9 +1899,9 @@ _wrap_goo_canvas_item_simple_changed(PyGObject *self, PyObject *args, PyObject * if (!PyArg_ParseTupleAndKeywords(args, kwargs,"i:GooCanvasItemSimple.changed", kwlist, &recompute_bounds)) return NULL; - + goo_canvas_item_simple_changed(GOO_CANVAS_ITEM_SIMPLE(self->obj), recompute_bounds); - + Py_INCREF(Py_None); return Py_None; } @@ -1786,9 +1909,9 @@ _wrap_goo_canvas_item_simple_changed(PyGObject *self, PyObject *args, PyObject * static PyObject * _wrap_goo_canvas_item_simple_check_style(PyGObject *self) { - + goo_canvas_item_simple_check_style(GOO_CANVAS_ITEM_SIMPLE(self->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -1798,9 +1921,9 @@ _wrap_goo_canvas_item_simple_get_line_width(PyGObject *self) { double ret; - + ret = goo_canvas_item_simple_get_line_width(GOO_CANVAS_ITEM_SIMPLE(self->obj)); - + return PyFloat_FromDouble(ret); } @@ -1812,9 +1935,9 @@ _wrap_goo_canvas_item_simple_set_model(PyGObject *self, PyObject *args, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItemSimple.set_model", kwlist, &PyGooCanvasItemModel_Type, &model)) return NULL; - + goo_canvas_item_simple_set_model(GOO_CANVAS_ITEM_SIMPLE(self->obj), GOO_CANVAS_ITEM_MODEL(model->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -1944,7 +2067,7 @@ static const PyMethodDef _PyGooCanvasItemSimple_methods[] = { { NULL, NULL, 0, NULL } }; -#line 783 "goocanvas.override" +#line 786 "goocanvas.override" static int _wrap_goo_canvas_item_simple__set_bounds_x1(PyGObject *self, PyObject *py_value, void *closure) @@ -1957,7 +2080,7 @@ _wrap_goo_canvas_item_simple__set_bounds_x1(PyGObject *self, PyObject *py_value, return 0; } -#line 1961 "goocanvas.c" +#line 2136 "goocanvas.c" static PyObject * @@ -1969,7 +2092,7 @@ _wrap_goo_canvas_item_simple__get_bounds_x1(PyObject *self, void *closure) return PyFloat_FromDouble(ret); } -#line 797 "goocanvas.override" +#line 800 "goocanvas.override" static int _wrap_goo_canvas_item_simple__set_bounds_x2(PyGObject *self, PyObject *py_value, void *closure) @@ -1982,7 +2105,7 @@ _wrap_goo_canvas_item_simple__set_bounds_x2(PyGObject *self, PyObject *py_value, return 0; } -#line 1986 "goocanvas.c" +#line 2161 "goocanvas.c" static PyObject * @@ -1994,7 +2117,7 @@ _wrap_goo_canvas_item_simple__get_bounds_x2(PyObject *self, void *closure) return PyFloat_FromDouble(ret); } -#line 811 "goocanvas.override" +#line 814 "goocanvas.override" static int _wrap_goo_canvas_item_simple__set_bounds_y1(PyGObject *self, PyObject *py_value, void *closure) @@ -2007,7 +2130,7 @@ _wrap_goo_canvas_item_simple__set_bounds_y1(PyGObject *self, PyObject *py_value, return 0; } -#line 2011 "goocanvas.c" +#line 2186 "goocanvas.c" static PyObject * @@ -2019,7 +2142,7 @@ _wrap_goo_canvas_item_simple__get_bounds_y1(PyObject *self, void *closure) return PyFloat_FromDouble(ret); } -#line 825 "goocanvas.override" +#line 828 "goocanvas.override" static int _wrap_goo_canvas_item_simple__set_bounds_y2(PyGObject *self, PyObject *py_value, void *closure) @@ -2032,7 +2155,7 @@ _wrap_goo_canvas_item_simple__set_bounds_y2(PyGObject *self, PyObject *py_value, return 0; } -#line 2036 "goocanvas.c" +#line 2211 "goocanvas.c" static PyObject * @@ -2044,7 +2167,7 @@ _wrap_goo_canvas_item_simple__get_bounds_y2(PyObject *self, void *closure) return PyFloat_FromDouble(ret); } -#line 1587 "goocanvas.override" +#line 1590 "goocanvas.override" static int _wrap_goo_canvas_item_simple__set_bounds(PyGObject *self, PyObject *py_value, void *closure) @@ -2062,7 +2185,8 @@ _wrap_goo_canvas_item_simple__get_bounds(PyGObject *self, void *closure) { return pygoo_canvas_bounds_new(&GOO_CANVAS_ITEM_SIMPLE(pygobject_get(self))->bounds); } -#line 2066 "goocanvas.c" + +#line 2242 "goocanvas.c" static const PyGetSetDef goo_canvas_item_simple_getsets[] = { @@ -2128,7 +2252,7 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_create_path(GooCanvasItemSimple *self PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -2137,11 +2261,11 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_create_path(GooCanvasItemSimple *self pyg_gil_state_release(__py_state); return; } - py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL); - + py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL); + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_cr); - + py_method = PyObject_GetAttrString(py_self, "do_simple_create_path"); if (!py_method) { if (PyErr_Occurred()) @@ -2172,8 +2296,8 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_create_path(GooCanvasItemSimple *self pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -2189,7 +2313,7 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_update(GooCanvasItemSimple *self, cai PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -2198,11 +2322,11 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_update(GooCanvasItemSimple *self, cai pyg_gil_state_release(__py_state); return; } - py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL); - + py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL); + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_cr); - + py_method = PyObject_GetAttrString(py_self, "do_simple_update"); if (!py_method) { if (PyErr_Occurred()) @@ -2233,8 +2357,8 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_update(GooCanvasItemSimple *self, cai pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -2251,7 +2375,7 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_paint(GooCanvasItemSimple *self, cair PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -2260,13 +2384,13 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_paint(GooCanvasItemSimple *self, cair pyg_gil_state_release(__py_state); return; } - py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL); + py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL); py_bounds = pygoo_canvas_bounds_new(bounds); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_cr); PyTuple_SET_ITEM(py_args, 1, py_bounds); - + py_method = PyObject_GetAttrString(py_self, "do_simple_paint"); if (!py_method) { if (PyErr_Occurred()) @@ -2297,8 +2421,8 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_paint(GooCanvasItemSimple *self, cair pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -2319,7 +2443,7 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_is_item_at(GooCanvasItemSimple *self, PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -2330,16 +2454,16 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_is_item_at(GooCanvasItemSimple *self, } py_x = PyFloat_FromDouble(x); py_y = PyFloat_FromDouble(y); - py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL); + py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL); py_is_pointer_event = is_pointer_event? Py_True : Py_False; - + py_args = PyTuple_New(4); PyTuple_SET_ITEM(py_args, 0, py_x); PyTuple_SET_ITEM(py_args, 1, py_y); PyTuple_SET_ITEM(py_args, 2, py_cr); Py_INCREF(py_is_pointer_event); PyTuple_SET_ITEM(py_args, 3, py_is_pointer_event); - + py_method = PyObject_GetAttrString(py_self, "do_simple_is_item_at"); if (!py_method) { if (PyErr_Occurred()) @@ -2371,15 +2495,15 @@ _wrap_GooCanvasItemSimple__proxy_do_simple_is_item_at(GooCanvasItemSimple *self, pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } @@ -2482,55 +2606,6 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasImage_Type = { -/* ----------- GooCanvasSvg ----------- */ - -PyTypeObject G_GNUC_INTERNAL PyGooCanvasSvg_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "goocanvas.Svg", /* tp_name */ - sizeof(PyGObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)0, /* tp_dealloc */ - (printfunc)0, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)0, /* tp_compare */ - (reprfunc)0, /* tp_repr */ - (PyNumberMethods*)0, /* tp_as_number */ - (PySequenceMethods*)0, /* tp_as_sequence */ - (PyMappingMethods*)0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)0, /* tp_str */ - (getattrofunc)0, /* tp_getattro */ - (setattrofunc)0, /* tp_setattro */ - (PyBufferProcs*)0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - NULL, /* Documentation string */ - (traverseproc)0, /* tp_traverse */ - (inquiry)0, /* tp_clear */ - (richcmpfunc)0, /* tp_richcompare */ - offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ - (getiterfunc)0, /* tp_iter */ - (iternextfunc)0, /* tp_iternext */ - (struct PyMethodDef*)NULL, /* tp_methods */ - (struct PyMemberDef*)0, /* tp_members */ - (struct PyGetSetDef*)0, /* tp_getset */ - NULL, /* tp_base */ - NULL, /* tp_dict */ - (descrgetfunc)0, /* tp_descr_get */ - (descrsetfunc)0, /* tp_descr_set */ - offsetof(PyGObject, inst_dict), /* tp_dictoffset */ - (initproc)0, /* tp_init */ - (allocfunc)0, /* tp_alloc */ - (newfunc)0, /* tp_new */ - (freefunc)0, /* tp_free */ - (inquiry)0 /* tp_is_gc */ -}; - - - /* ----------- GooCanvasGroup ----------- */ PyTypeObject G_GNUC_INTERNAL PyGooCanvasGroup_Type = { @@ -2930,9 +3005,9 @@ _wrap_goo_canvas_style_copy(PyGObject *self) { GooCanvasStyle *ret; - + ret = goo_canvas_style_copy(GOO_CANVAS_STYLE(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -2942,9 +3017,9 @@ _wrap_goo_canvas_style_get_parent(PyGObject *self) { GooCanvasStyle *ret; - + ret = goo_canvas_style_get_parent(GOO_CANVAS_STYLE(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -2957,14 +3032,14 @@ _wrap_goo_canvas_style_set_parent(PyGObject *self, PyObject *args, PyObject *kwa if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasStyle.set_parent", kwlist, &PyGooCanvasStyle_Type, &parent)) return NULL; - + goo_canvas_style_set_parent(GOO_CANVAS_STYLE(self->obj), GOO_CANVAS_STYLE(parent->obj)); - + Py_INCREF(Py_None); return Py_None; } -#line 716 "goocanvas.override" +#line 719 "goocanvas.override" static PyObject * _wrap_goo_canvas_style_get_property(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -2977,10 +3052,10 @@ _wrap_goo_canvas_style_get_property(PyGObject *self, PyObject *args, PyObject *k return _py_canvas_style_get_property(GOO_CANVAS_STYLE(self->obj), name); } -#line 2981 "goocanvas.c" +#line 3157 "goocanvas.c" -#line 730 "goocanvas.override" +#line 733 "goocanvas.override" static PyObject * _wrap_goo_canvas_style_set_property(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -2997,7 +3072,7 @@ _wrap_goo_canvas_style_set_property(PyGObject *self, PyObject *args, PyObject *k return Py_None; } -#line 3001 "goocanvas.c" +#line 3177 "goocanvas.c" static PyObject * @@ -3009,9 +3084,9 @@ _wrap_goo_canvas_style_set_stroke_options(PyGObject *self, PyObject *args, PyObj if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasStyle.set_stroke_options", kwlist, &PycairoContext_Type, &cr)) return NULL; - + ret = goo_canvas_style_set_stroke_options(GOO_CANVAS_STYLE(self->obj), cr->ctx); - + return PyBool_FromLong(ret); } @@ -3025,9 +3100,9 @@ _wrap_goo_canvas_style_set_fill_options(PyGObject *self, PyObject *args, PyObjec if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasStyle.set_fill_options", kwlist, &PycairoContext_Type, &cr)) return NULL; - + ret = goo_canvas_style_set_fill_options(GOO_CANVAS_STYLE(self->obj), cr->ctx); - + return PyBool_FromLong(ret); } @@ -3050,7 +3125,7 @@ static const PyMethodDef _PyGooCanvasStyle_methods[] = { { NULL, NULL, 0, NULL } }; -#line 748 "goocanvas.override" +#line 751 "goocanvas.override" static PyObject * goo_canvas_style_subscript(PyGObject *self, PyObject *arg) @@ -3084,7 +3159,7 @@ static PyMappingMethods _wrap_goo_canvas_style_tp_as_mapping = { (objobjargproc) _wrap_goo_canvas_style_ass_subscript, /* objobjargproc mp_ass_subscript; */ }; -#line 3088 "goocanvas.c" +#line 3264 "goocanvas.c" PyTypeObject G_GNUC_INTERNAL PyGooCanvasStyle_Type = { @@ -3234,6 +3309,31 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasTableModel_Type = { /* ----------- GooCanvasText ----------- */ +#line 1610 "goocanvas.override" +static PyObject * +_wrap_goo_canvas_text_get_natural_extents(PyGObject *self) +{ + PangoRectangle ink_rect, logical_rect; + + goo_canvas_text_get_natural_extents(GOO_CANVAS_TEXT(self->obj), &ink_rect, + &logical_rect); + + return Py_BuildValue("((iiii)(iiii))", + ink_rect.x, ink_rect.y, + ink_rect.width, ink_rect.height, + logical_rect.x, logical_rect.y, + logical_rect.width, logical_rect.height); +} + +#line 3430 "goocanvas.c" + + +static const PyMethodDef _PyGooCanvasText_methods[] = { + { "get_natural_extents", (PyCFunction)_wrap_goo_canvas_text_get_natural_extents, METH_NOARGS, + NULL }, + { NULL, NULL, 0, NULL } +}; + PyTypeObject G_GNUC_INTERNAL PyGooCanvasText_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ @@ -3264,7 +3364,7 @@ PyTypeObject G_GNUC_INTERNAL PyGooCanvasText_Type = { offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ (getiterfunc)0, /* tp_iter */ (iternextfunc)0, /* tp_iternext */ - (struct PyMethodDef*)NULL, /* tp_methods */ + (struct PyMethodDef*)_PyGooCanvasText_methods, /* tp_methods */ (struct PyMemberDef*)0, /* tp_members */ (struct PyGetSetDef*)0, /* tp_getset */ NULL, /* tp_base */ @@ -3386,9 +3486,9 @@ _wrap_goo_canvas_item_get_n_children(PyGObject *self) { int ret; - + ret = goo_canvas_item_get_n_children(GOO_CANVAS_ITEM(self->obj)); - + return PyInt_FromLong(ret); } @@ -3401,9 +3501,9 @@ _wrap_goo_canvas_item_get_child(PyGObject *self, PyObject *args, PyObject *kwarg if (!PyArg_ParseTupleAndKeywords(args, kwargs,"i:GooCanvasItem.get_child", kwlist, &child_num)) return NULL; - + ret = goo_canvas_item_get_child(GOO_CANVAS_ITEM(self->obj), child_num); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -3417,9 +3517,9 @@ _wrap_goo_canvas_item_find_child(PyGObject *self, PyObject *args, PyObject *kwar if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItem.find_child", kwlist, &PyGooCanvasItem_Type, &child)) return NULL; - + ret = goo_canvas_item_find_child(GOO_CANVAS_ITEM(self->obj), GOO_CANVAS_ITEM(child->obj)); - + return PyInt_FromLong(ret); } @@ -3432,9 +3532,9 @@ _wrap_goo_canvas_item_add_child(PyGObject *self, PyObject *args, PyObject *kwarg if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!|i:GooCanvasItem.add_child", kwlist, &PyGooCanvasItem_Type, &child, &position)) return NULL; - + goo_canvas_item_add_child(GOO_CANVAS_ITEM(self->obj), GOO_CANVAS_ITEM(child->obj), position); - + Py_INCREF(Py_None); return Py_None; } @@ -3447,14 +3547,14 @@ _wrap_goo_canvas_item_move_child(PyGObject *self, PyObject *args, PyObject *kwar if (!PyArg_ParseTupleAndKeywords(args, kwargs,"ii:GooCanvasItem.move_child", kwlist, &old_position, &new_position)) return NULL; - + goo_canvas_item_move_child(GOO_CANVAS_ITEM(self->obj), old_position, new_position); - + Py_INCREF(Py_None); return Py_None; } -#line 483 "goocanvas.override" +#line 486 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_remove_child(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -3483,10 +3583,129 @@ _wrap_goo_canvas_item_remove_child(PyGObject *self, PyObject *args, PyObject *kw Py_INCREF(Py_None); return Py_None; } -#line 3487 "goocanvas.c" +#line 3688 "goocanvas.c" -#line 921 "goocanvas.override" +#line 1711 "goocanvas.override" +static PyObject * +_wrap_goo_canvas_item_get_child_property(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "child", "property", NULL }; + PyGObject *pychild; + gchar *property_name; + GooCanvasItem *item, *child; + GObjectClass *class; + GParamSpec *pspec; + GValue value = { 0, } ; + PyObject *ret; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!s:GooCanvasItem.get_child_property", + kwlist, &PyGooCanvasItem_Type, &pychild, + &property_name)) { + return NULL; + } + + item = GOO_CANVAS_ITEM(self->obj); + child = GOO_CANVAS_ITEM(pychild->obj); + + if (goo_canvas_item_find_child(item, child) == -1) { + PyErr_SetString(PyExc_TypeError, + "first argument must be a child"); + return NULL; + } + + class = G_OBJECT_GET_CLASS(item); + pspec = goo_canvas_item_class_find_child_property(class, property_name); + if (!pspec) { + gchar buf[512]; + g_snprintf(buf, sizeof(buf), + "item does not support property `%s'", + property_name); + + PyErr_SetString(PyExc_TypeError, buf); + return NULL; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + goo_canvas_item_get_child_property(item, + child, + property_name, + &value); + + ret = pyg_value_as_pyobject(&value, TRUE); + g_value_unset(&value); + + return ret; +} + +#line 3747 "goocanvas.c" + + +#line 1653 "goocanvas.override" +static PyObject * +_wrap_goo_canvas_item_set_child_property(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "child", "property", "value", NULL }; + gchar *property_name; + PyGObject *pychild; + GooCanvasItem *item, *child; + PyGObject *pyvalue; + GObjectClass *class; + GParamSpec *pspec; + GValue value = { 0, } ; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!sO:GooCanvasItem.set_child_property", + kwlist, + &PyGooCanvasItem_Type, &pychild, + &property_name, &pyvalue)) { + return NULL; + } + + item = GOO_CANVAS_ITEM(self->obj); + child = GOO_CANVAS_ITEM(pychild->obj); + + if (goo_canvas_item_find_child(item, child) == -1) { + PyErr_SetString(PyExc_TypeError, + "first argument must be a child"); + return NULL; + } + + class = G_OBJECT_GET_CLASS(self->obj); + pspec = goo_canvas_item_class_find_child_property(class, property_name); + if (!pspec) { + gchar buf[512]; + g_snprintf(buf, sizeof(buf), + "item does not support property `%s'", + property_name); + PyErr_SetString(PyExc_TypeError, buf); + + return NULL; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + pyg_value_from_pyobject(&value, (PyObject*)pyvalue); + + goo_canvas_item_set_child_property(item, + child, + property_name, + &value); + g_value_unset(&value); + Py_INCREF(Py_None); + return Py_None; +} + +#line 3807 "goocanvas.c" + + +#line 924 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_get_child_properties(PyGObject *self, PyObject *args) { @@ -3567,10 +3786,10 @@ _wrap_goo_canvas_item_get_child_properties(PyGObject *self, PyObject *args) return tuple; } -#line 3571 "goocanvas.c" +#line 3891 "goocanvas.c" -#line 839 "goocanvas.override" +#line 842 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_set_child_properties(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -3651,36 +3870,47 @@ _wrap_goo_canvas_item_set_child_properties(PyGObject *self, PyObject *args, PyOb return Py_None; } -#line 3655 "goocanvas.c" +#line 3975 "goocanvas.c" +#line 1953 "goocanvas.override" static PyObject * -_wrap_goo_canvas_item_get_transform_for_child(PyGObject *self, PyObject *args, PyObject *kwargs) +_wrap_goo_canvas_item_get_transform_for_child(PyGObject *self, + PyObject *args, + PyObject *kwargs) { - static char *kwlist[] = { "child", "transform", NULL }; + static char *kwlist[] = { "child", NULL }; PyGObject *child; - PyObject *py_transform; int ret; - cairo_matrix_t *transform; + cairo_matrix_t *transform = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O:GooCanvasItem.get_transform_for_child", kwlist, &PyGooCanvasItem_Type, &child, &py_transform)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!:GooCanvasItem.get_transform_for_child", + kwlist, &PyGooCanvasItem_Type, &child)) return NULL; - transform = &((PycairoMatrix*)(py_transform))->matrix; - - ret = goo_canvas_item_get_transform_for_child(GOO_CANVAS_ITEM(self->obj), GOO_CANVAS_ITEM(child->obj), transform); - - return PyBool_FromLong(ret); + ret = goo_canvas_item_get_transform_for_child(GOO_CANVAS_ITEM(self->obj), + GOO_CANVAS_ITEM(child->obj), + transform); + + if (ret) + return PycairoMatrix_FromMatrix(transform); + else + Py_INCREF(Py_None); + return Py_None; } +#line 4005 "goocanvas.c" + + static PyObject * _wrap_goo_canvas_item_get_canvas(PyGObject *self) { GooCanvas *ret; - + ret = goo_canvas_item_get_canvas(GOO_CANVAS_ITEM(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -3693,9 +3923,9 @@ _wrap_goo_canvas_item_set_canvas(PyGObject *self, PyObject *args, PyObject *kwar if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItem.set_canvas", kwlist, &PyGooCanvas_Type, &canvas)) return NULL; - + goo_canvas_item_set_canvas(GOO_CANVAS_ITEM(self->obj), GOO_CANVAS(canvas->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -3705,9 +3935,9 @@ _wrap_goo_canvas_item_get_parent(PyGObject *self) { GooCanvasItem *ret; - + ret = goo_canvas_item_get_parent(GOO_CANVAS_ITEM(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -3720,9 +3950,9 @@ _wrap_goo_canvas_item_set_parent(PyGObject *self, PyObject *args, PyObject *kwar if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItem.set_parent", kwlist, &PyGooCanvasItem_Type, &parent)) return NULL; - + goo_canvas_item_set_parent(GOO_CANVAS_ITEM(self->obj), GOO_CANVAS_ITEM(parent->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -3730,9 +3960,9 @@ _wrap_goo_canvas_item_set_parent(PyGObject *self, PyObject *args, PyObject *kwar static PyObject * _wrap_goo_canvas_item_remove(PyGObject *self) { - + goo_canvas_item_remove(GOO_CANVAS_ITEM(self->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -3742,9 +3972,9 @@ _wrap_goo_canvas_item_is_container(PyGObject *self) { int ret; - + ret = goo_canvas_item_is_container(GOO_CANVAS_ITEM(self->obj)); - + return PyBool_FromLong(ret); } @@ -3764,9 +3994,9 @@ _wrap_goo_canvas_item_raise(PyGObject *self, PyObject *args, PyObject *kwargs) PyErr_SetString(PyExc_TypeError, "above should be a GooCanvasItem or None"); return NULL; } - + goo_canvas_item_raise(GOO_CANVAS_ITEM(self->obj), (GooCanvasItem *) above); - + Py_INCREF(Py_None); return Py_None; } @@ -3786,14 +4016,14 @@ _wrap_goo_canvas_item_lower(PyGObject *self, PyObject *args, PyObject *kwargs) PyErr_SetString(PyExc_TypeError, "below should be a GooCanvasItem or None"); return NULL; } - + goo_canvas_item_lower(GOO_CANVAS_ITEM(self->obj), (GooCanvasItem *) below); - + Py_INCREF(Py_None); return Py_None; } -#line 1546 "goocanvas.override" +#line 1549 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_get_transform(PyGObject *self) { @@ -3812,26 +4042,51 @@ _wrap_goo_canvas_item_get_transform(PyGObject *self) return matrix; } -#line 3816 "goocanvas.c" +#line 4147 "goocanvas.c" +#line 1981 "goocanvas.override" static PyObject * -_wrap_goo_canvas_item_set_transform(PyGObject *self, PyObject *args, PyObject *kwargs) +_wrap_goo_canvas_item_set_transform(PyGObject *self, + PyObject *args, + PyObject *kwargs) { static char *kwlist[] = { "matrix", NULL }; PyObject *py_matrix; - cairo_matrix_t *matrix; + cairo_matrix_t *matrix = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O:GooCanvasItem.set_transform", kwlist, &py_matrix)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:GooCanvasItem.set_transform", + kwlist, &py_matrix)) return NULL; - matrix = &((PycairoMatrix*)(py_matrix))->matrix; - + + if (py_matrix && (py_matrix != Py_None)) + matrix = &((PycairoMatrix*)(py_matrix))->matrix; + goo_canvas_item_set_transform(GOO_CANVAS_ITEM(self->obj), matrix); - + Py_INCREF(Py_None); return Py_None; } +#line 4174 "goocanvas.c" + + +#line 1627 "goocanvas.override" +static PyObject * +_wrap_goo_canvas_item_get_simple_transform(PyGObject *self) +{ + gdouble x, y, scale, rotation; + + goo_canvas_item_get_simple_transform(GOO_CANVAS_ITEM(self->obj), &x, &y, + &scale, &rotation); + + return Py_BuildValue("dddd", x, y, scale, rotation); +} + +#line 4189 "goocanvas.c" + + static PyObject * _wrap_goo_canvas_item_set_simple_transform(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -3840,9 +4095,9 @@ _wrap_goo_canvas_item_set_simple_transform(PyGObject *self, PyObject *args, PyOb if (!PyArg_ParseTupleAndKeywords(args, kwargs,"dddd:GooCanvasItem.set_simple_transform", kwlist, &x, &y, &scale, &rotation)) return NULL; - + goo_canvas_item_set_simple_transform(GOO_CANVAS_ITEM(self->obj), x, y, scale, rotation); - + Py_INCREF(Py_None); return Py_None; } @@ -3855,9 +4110,9 @@ _wrap_goo_canvas_item_translate(PyGObject *self, PyObject *args, PyObject *kwarg if (!PyArg_ParseTupleAndKeywords(args, kwargs,"dd:GooCanvasItem.translate", kwlist, &tx, &ty)) return NULL; - + goo_canvas_item_translate(GOO_CANVAS_ITEM(self->obj), tx, ty); - + Py_INCREF(Py_None); return Py_None; } @@ -3870,9 +4125,9 @@ _wrap_goo_canvas_item_scale(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"dd:GooCanvasItem.scale", kwlist, &sx, &sy)) return NULL; - + goo_canvas_item_scale(GOO_CANVAS_ITEM(self->obj), sx, sy); - + Py_INCREF(Py_None); return Py_None; } @@ -3885,9 +4140,9 @@ _wrap_goo_canvas_item_rotate(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"ddd:GooCanvasItem.rotate", kwlist, °rees, &cx, &cy)) return NULL; - + goo_canvas_item_rotate(GOO_CANVAS_ITEM(self->obj), degrees, cx, cy); - + Py_INCREF(Py_None); return Py_None; } @@ -3900,9 +4155,9 @@ _wrap_goo_canvas_item_skew_x(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"ddd:GooCanvasItem.skew_x", kwlist, °rees, &cx, &cy)) return NULL; - + goo_canvas_item_skew_x(GOO_CANVAS_ITEM(self->obj), degrees, cx, cy); - + Py_INCREF(Py_None); return Py_None; } @@ -3915,9 +4170,9 @@ _wrap_goo_canvas_item_skew_y(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"ddd:GooCanvasItem.skew_y", kwlist, °rees, &cx, &cy)) return NULL; - + goo_canvas_item_skew_y(GOO_CANVAS_ITEM(self->obj), degrees, cx, cy); - + Py_INCREF(Py_None); return Py_None; } @@ -3927,9 +4182,9 @@ _wrap_goo_canvas_item_get_style(PyGObject *self) { GooCanvasStyle *ret; - + ret = goo_canvas_item_get_style(GOO_CANVAS_ITEM(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -3942,9 +4197,9 @@ _wrap_goo_canvas_item_set_style(PyGObject *self, PyObject *args, PyObject *kwarg if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItem.set_style", kwlist, &PyGooCanvasStyle_Type, &style)) return NULL; - + goo_canvas_item_set_style(GOO_CANVAS_ITEM(self->obj), GOO_CANVAS_STYLE(style->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -3962,9 +4217,9 @@ _wrap_goo_canvas_item_animate(PyGObject *self, PyObject *args, PyObject *kwargs) return NULL; if (pyg_enum_get_value(GOO_TYPE_CANVAS_ANIMATE_TYPE, py_type, (gpointer)&type)) return NULL; - + goo_canvas_item_animate(GOO_CANVAS_ITEM(self->obj), x, y, scale, degrees, absolute, duration, step_time, type); - + Py_INCREF(Py_None); return Py_None; } @@ -3972,14 +4227,14 @@ _wrap_goo_canvas_item_animate(PyGObject *self, PyObject *args, PyObject *kwargs) static PyObject * _wrap_goo_canvas_item_stop_animation(PyGObject *self) { - + goo_canvas_item_stop_animation(GOO_CANVAS_ITEM(self->obj)); - + Py_INCREF(Py_None); return Py_None; } -#line 525 "goocanvas.override" +#line 528 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_get_bounds(PyGObject *self) { @@ -3993,10 +4248,10 @@ _wrap_goo_canvas_item_get_bounds(PyGObject *self) return py_bounds; } -#line 3997 "goocanvas.c" +#line 4353 "goocanvas.c" -#line 1508 "goocanvas.override" +#line 1511 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_get_items_at(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -4033,7 +4288,7 @@ _wrap_goo_canvas_item_get_items_at(PyGObject *self, PyObject *args, PyObject *kw return ret; } -#line 4037 "goocanvas.c" +#line 4393 "goocanvas.c" static PyObject * @@ -4041,9 +4296,9 @@ _wrap_goo_canvas_item_is_visible(PyGObject *self) { int ret; - + ret = goo_canvas_item_is_visible(GOO_CANVAS_ITEM(self->obj)); - + return PyBool_FromLong(ret); } @@ -4053,9 +4308,9 @@ _wrap_goo_canvas_item_get_model(PyGObject *self) { GooCanvasItemModel *ret; - + ret = goo_canvas_item_get_model(GOO_CANVAS_ITEM(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -4068,9 +4323,9 @@ _wrap_goo_canvas_item_set_model(PyGObject *self, PyObject *args, PyObject *kwarg if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItem.set_model", kwlist, &PyGooCanvasItemModel_Type, &model)) return NULL; - + goo_canvas_item_set_model(GOO_CANVAS_ITEM(self->obj), GOO_CANVAS_ITEM_MODEL(model->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -4078,9 +4333,9 @@ _wrap_goo_canvas_item_set_model(PyGObject *self, PyObject *args, PyObject *kwarg static PyObject * _wrap_goo_canvas_item_request_update(PyGObject *self) { - + goo_canvas_item_request_update(GOO_CANVAS_ITEM(self->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -4088,30 +4343,36 @@ _wrap_goo_canvas_item_request_update(PyGObject *self) static PyObject * _wrap_goo_canvas_item_ensure_updated(PyGObject *self) { - + goo_canvas_item_ensure_updated(GOO_CANVAS_ITEM(self->obj)); - + Py_INCREF(Py_None); return Py_None; } +#line 1932 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_update(PyGObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = { "entire_tree", "cr", "bounds", NULL }; - int entire_tree; - PyObject *py_bounds; - PycairoContext *cr; + static char *kwlist[] = { "entire_tree", "cr", NULL }; + int entire_tree; + PycairoContext *cr; + GooCanvasBounds bounds; - if (!PyArg_ParseTupleAndKeywords(args, kwargs,"iO!O!:GooCanvasItem.update", kwlist, &entire_tree, &PycairoContext_Type, &cr, &PyGooCanvasBounds_Type, &py_bounds)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"iO!:GooCanvasItem.update", + kwlist, &entire_tree, + &PycairoContext_Type, &cr)) return NULL; - - goo_canvas_item_update(GOO_CANVAS_ITEM(self->obj), entire_tree, cr->ctx, (py_bounds == NULL)? NULL : &((PyGooCanvasBounds *) py_bounds)->bounds); - - Py_INCREF(Py_None); - return Py_None; + + goo_canvas_item_update(GOO_CANVAS_ITEM(self->obj), entire_tree, + cr->ctx, &bounds); + + return pygoo_canvas_bounds_new(&bounds); } +#line 4475 "goocanvas.c" + + static PyObject * _wrap_goo_canvas_item_paint(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -4122,35 +4383,43 @@ _wrap_goo_canvas_item_paint(PyGObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!|Od:GooCanvasItem.paint", kwlist, &PycairoContext_Type, &cr, &py_bounds, &scale)) return NULL; - if (!(py_bounds == NULL || py_bounds == Py_None || + if (!(py_bounds == NULL || py_bounds == Py_None || PyObject_IsInstance(py_bounds, (PyObject *) &PyGooCanvasBounds_Type))) { PyErr_SetString(PyExc_TypeError, "parameter bounds must be goocanvas.Bounds or None"); return NULL; } - + goo_canvas_item_paint(GOO_CANVAS_ITEM(self->obj), cr->ctx, (py_bounds == NULL || py_bounds == Py_None)? NULL : &((PyGooCanvasBounds *) py_bounds)->bounds, scale); - + Py_INCREF(Py_None); return Py_None; } +#line 1909 "goocanvas.override" static PyObject * -_wrap_goo_canvas_item_get_requested_area(PyGObject *self, PyObject *args, PyObject *kwargs) +_wrap_goo_canvas_item_get_requested_area(PyGObject *self, + PyObject *args, + PyObject *kwargs) { - static char *kwlist[] = { "cr", "requested_area", NULL }; - PyObject *py_requested_area; - int ret; - PycairoContext *cr; + static char *kwlist[] = { "cr", NULL }; + int ret; + GooCanvasBounds bounds; + PycairoContext *cr; - if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O!:GooCanvasItem.get_requested_area", kwlist, &PycairoContext_Type, &cr, &PyGooCanvasBounds_Type, &py_requested_area)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!:GooCanvasItem.get_requested_area", + kwlist, &PycairoContext_Type, &cr)) return NULL; - - ret = goo_canvas_item_get_requested_area(GOO_CANVAS_ITEM(self->obj), cr->ctx, (py_requested_area == NULL)? NULL : &((PyGooCanvasBounds *) py_requested_area)->bounds); - - return PyBool_FromLong(ret); + ret = goo_canvas_item_get_requested_area(GOO_CANVAS_ITEM(self->obj), + cr->ctx, &bounds); + + return pygoo_canvas_bounds_new(&bounds); } +#line 4522 "goocanvas.c" + + static PyObject * _wrap_goo_canvas_item_get_requested_height(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -4160,9 +4429,9 @@ _wrap_goo_canvas_item_get_requested_height(PyGObject *self, PyObject *args, PyOb if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!d:GooCanvasItem.get_requested_height", kwlist, &PycairoContext_Type, &cr, &width)) return NULL; - + ret = goo_canvas_item_get_requested_height(GOO_CANVAS_ITEM(self->obj), cr->ctx, width); - + return PyFloat_FromDouble(ret); } @@ -4176,14 +4445,14 @@ _wrap_goo_canvas_item_allocate_area(PyGObject *self, PyObject *args, PyObject *k if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O!O!dd:GooCanvasItem.allocate_area", kwlist, &PycairoContext_Type, &cr, &PyGooCanvasBounds_Type, &py_requested_area, &PyGooCanvasBounds_Type, &py_allocated_area, &x_offset, &y_offset)) return NULL; - + goo_canvas_item_allocate_area(GOO_CANVAS_ITEM(self->obj), cr->ctx, (py_requested_area == NULL)? NULL : &((PyGooCanvasBounds *) py_requested_area)->bounds, (py_allocated_area == NULL)? NULL : &((PyGooCanvasBounds *) py_allocated_area)->bounds, x_offset, y_offset); - + Py_INCREF(Py_None); return Py_None; } -#line 1208 "goocanvas.override" +#line 1211 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_find_child_property (PyObject *cls, PyObject *args, @@ -4223,10 +4492,10 @@ _wrap_goo_canvas_item_find_child_property (PyObject *cls, return pyg_param_spec_new(pspec); } -#line 4227 "goocanvas.c" +#line 4597 "goocanvas.c" -#line 1291 "goocanvas.override" +#line 1294 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_list_child_properties (PyObject *cls, PyObject *args, @@ -4267,10 +4536,10 @@ _wrap_goo_canvas_item_list_child_properties (PyObject *cls, return list; } -#line 4271 "goocanvas.c" +#line 4641 "goocanvas.c" -#line 1385 "goocanvas.override" +#line 1388 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_install_child_property (PyObject *cls, PyObject *args, @@ -4321,7 +4590,7 @@ _wrap_goo_canvas_item_install_child_property (PyObject *cls, return Py_None; } -#line 4325 "goocanvas.c" +#line 4695 "goocanvas.c" static PyObject * @@ -5142,6 +5411,10 @@ static const PyMethodDef _PyGooCanvasItem_methods[] = { NULL }, { "remove_child", (PyCFunction)_wrap_goo_canvas_item_remove_child, METH_VARARGS|METH_KEYWORDS, NULL }, + { "get_child_property", (PyCFunction)_wrap_goo_canvas_item_get_child_property, METH_VARARGS, + NULL }, + { "set_child_property", (PyCFunction)_wrap_goo_canvas_item_set_child_property, METH_VARARGS|METH_KEYWORDS, + NULL }, { "get_child_properties", (PyCFunction)_wrap_goo_canvas_item_get_child_properties, METH_VARARGS, NULL }, { "set_child_properties", (PyCFunction)_wrap_goo_canvas_item_set_child_properties, METH_VARARGS|METH_KEYWORDS, @@ -5168,6 +5441,8 @@ static const PyMethodDef _PyGooCanvasItem_methods[] = { NULL }, { "set_transform", (PyCFunction)_wrap_goo_canvas_item_set_transform, METH_VARARGS|METH_KEYWORDS, NULL }, + { "get_simple_transform", (PyCFunction)_wrap_goo_canvas_item_get_simple_transform, METH_NOARGS, + NULL }, { "set_simple_transform", (PyCFunction)_wrap_goo_canvas_item_set_simple_transform, METH_VARARGS|METH_KEYWORDS, NULL }, { "translate", (PyCFunction)_wrap_goo_canvas_item_translate, METH_VARARGS|METH_KEYWORDS, @@ -5342,7 +5617,7 @@ _wrap_GooCanvasItem__proxy_do_get_canvas(GooCanvasItem *self) GooCanvas* retval; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5351,8 +5626,8 @@ _wrap_GooCanvasItem__proxy_do_get_canvas(GooCanvasItem *self) pyg_gil_state_release(__py_state); return NULL; } - - + + py_method = PyObject_GetAttrString(py_self, "do_get_canvas"); if (!py_method) { if (PyErr_Occurred()) @@ -5391,13 +5666,13 @@ _wrap_GooCanvasItem__proxy_do_get_canvas(GooCanvasItem *self) } retval = (GooCanvas*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -5409,7 +5684,7 @@ _wrap_GooCanvasItem__proxy_do_set_canvas(GooCanvasItem *self, GooCanvas*canvas) PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5424,10 +5699,10 @@ _wrap_GooCanvasItem__proxy_do_set_canvas(GooCanvasItem *self, GooCanvas*canvas) Py_INCREF(Py_None); py_canvas = Py_None; } - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_canvas); - + py_method = PyObject_GetAttrString(py_self, "do_set_canvas"); if (!py_method) { if (PyErr_Occurred()) @@ -5458,8 +5733,8 @@ _wrap_GooCanvasItem__proxy_do_set_canvas(GooCanvasItem *self, GooCanvas*canvas) pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -5474,7 +5749,7 @@ _wrap_GooCanvasItem__proxy_do_get_n_children(GooCanvasItem *self) gint retval; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5483,8 +5758,8 @@ _wrap_GooCanvasItem__proxy_do_get_n_children(GooCanvasItem *self) pyg_gil_state_release(__py_state); return -G_MAXINT; } - - + + py_method = PyObject_GetAttrString(py_self, "do_get_n_children"); if (!py_method) { if (PyErr_Occurred()) @@ -5513,13 +5788,13 @@ _wrap_GooCanvasItem__proxy_do_get_n_children(GooCanvasItem *self) pyg_gil_state_release(__py_state); return -G_MAXINT; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static GooCanvasItem* @@ -5532,7 +5807,7 @@ _wrap_GooCanvasItem__proxy_do_get_child(GooCanvasItem *self, gint child_num) PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5542,10 +5817,10 @@ _wrap_GooCanvasItem__proxy_do_get_child(GooCanvasItem *self, gint child_num) return NULL; } py_child_num = PyInt_FromLong(child_num); - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_child_num); - + py_method = PyObject_GetAttrString(py_self, "do_get_child"); if (!py_method) { if (PyErr_Occurred()) @@ -5588,14 +5863,14 @@ _wrap_GooCanvasItem__proxy_do_get_child(GooCanvasItem *self, gint child_num) } retval = (GooCanvasItem*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -5605,7 +5880,7 @@ _wrap_GooCanvasItem__proxy_do_request_update(GooCanvasItem *self) PyObject *py_self; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5614,8 +5889,8 @@ _wrap_GooCanvasItem__proxy_do_request_update(GooCanvasItem *self) pyg_gil_state_release(__py_state); return; } - - + + py_method = PyObject_GetAttrString(py_self, "do_request_update"); if (!py_method) { if (PyErr_Occurred()) @@ -5643,8 +5918,8 @@ _wrap_GooCanvasItem__proxy_do_request_update(GooCanvasItem *self) pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); @@ -5660,7 +5935,7 @@ _wrap_GooCanvasItem__proxy_do_add_child(GooCanvasItem *self, GooCanvasItem*child PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5676,11 +5951,11 @@ _wrap_GooCanvasItem__proxy_do_add_child(GooCanvasItem *self, GooCanvasItem*child py_child = Py_None; } py_position = PyInt_FromLong(position); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_child); PyTuple_SET_ITEM(py_args, 1, py_position); - + py_method = PyObject_GetAttrString(py_self, "do_add_child"); if (!py_method) { if (PyErr_Occurred()) @@ -5711,8 +5986,8 @@ _wrap_GooCanvasItem__proxy_do_add_child(GooCanvasItem *self, GooCanvasItem*child pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -5729,7 +6004,7 @@ _wrap_GooCanvasItem__proxy_do_move_child(GooCanvasItem *self, gint old_position, PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5740,11 +6015,11 @@ _wrap_GooCanvasItem__proxy_do_move_child(GooCanvasItem *self, gint old_position, } py_old_position = PyInt_FromLong(old_position); py_new_position = PyInt_FromLong(new_position); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_old_position); PyTuple_SET_ITEM(py_args, 1, py_new_position); - + py_method = PyObject_GetAttrString(py_self, "do_move_child"); if (!py_method) { if (PyErr_Occurred()) @@ -5775,8 +6050,8 @@ _wrap_GooCanvasItem__proxy_do_move_child(GooCanvasItem *self, gint old_position, pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -5792,7 +6067,7 @@ _wrap_GooCanvasItem__proxy_do_remove_child(GooCanvasItem *self, gint child_num) PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5802,10 +6077,10 @@ _wrap_GooCanvasItem__proxy_do_remove_child(GooCanvasItem *self, gint child_num) return; } py_child_num = PyInt_FromLong(child_num); - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_child_num); - + py_method = PyObject_GetAttrString(py_self, "do_remove_child"); if (!py_method) { if (PyErr_Occurred()) @@ -5836,8 +6111,8 @@ _wrap_GooCanvasItem__proxy_do_remove_child(GooCanvasItem *self, gint child_num) pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -5852,7 +6127,7 @@ _wrap_GooCanvasItem__proxy_do_get_parent(GooCanvasItem *self) GooCanvasItem* retval; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5861,8 +6136,8 @@ _wrap_GooCanvasItem__proxy_do_get_parent(GooCanvasItem *self) pyg_gil_state_release(__py_state); return NULL; } - - + + py_method = PyObject_GetAttrString(py_self, "do_get_parent"); if (!py_method) { if (PyErr_Occurred()) @@ -5901,13 +6176,13 @@ _wrap_GooCanvasItem__proxy_do_get_parent(GooCanvasItem *self) } retval = (GooCanvasItem*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -5919,7 +6194,7 @@ _wrap_GooCanvasItem__proxy_do_set_parent(GooCanvasItem *self, GooCanvasItem*pare PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -5934,10 +6209,10 @@ _wrap_GooCanvasItem__proxy_do_set_parent(GooCanvasItem *self, GooCanvasItem*pare Py_INCREF(Py_None); py_parent = Py_None; } - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_parent); - + py_method = PyObject_GetAttrString(py_self, "do_set_parent"); if (!py_method) { if (PyErr_Occurred()) @@ -5968,15 +6243,15 @@ _wrap_GooCanvasItem__proxy_do_set_parent(GooCanvasItem *self, GooCanvasItem*pare pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); } -#line 606 "goocanvas.override" +#line 609 "goocanvas.override" static void _wrap_GooCanvasItem__proxy_do_get_bounds(GooCanvasItem *self, GooCanvasBounds *bounds) { @@ -6002,10 +6277,10 @@ _wrap_GooCanvasItem__proxy_do_get_bounds(GooCanvasItem *self, GooCanvasBounds *b Py_XDECREF(py_bounds); pyg_gil_state_release(__py_state); } -#line 6006 "goocanvas.c" +#line 6382 "goocanvas.c" -#line 633 "goocanvas.override" +#line 636 "goocanvas.override" static void _wrap_GooCanvasItem__proxy_do_update(GooCanvasItem *self, gboolean entire_tree, cairo_t *cr, GooCanvasBounds *bounds) @@ -6025,7 +6300,7 @@ _wrap_GooCanvasItem__proxy_do_update(GooCanvasItem *self, gboolean entire_tree, py_bounds = PyObject_CallMethod(py_self, "do_update", "iN", entire_tree, - PycairoContext_FromContext(cairo_reference(cr), NULL, NULL)); + PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL)); if (py_bounds) *bounds = ((PyGooCanvasBounds *) py_bounds)->bounds; else @@ -6035,7 +6310,7 @@ _wrap_GooCanvasItem__proxy_do_update(GooCanvasItem *self, gboolean entire_tree, pyg_gil_state_release(__py_state); } -#line 6039 "goocanvas.c" +#line 6415 "goocanvas.c" static void @@ -6049,7 +6324,7 @@ _wrap_GooCanvasItem__proxy_do_paint(GooCanvasItem *self, cairo_t*cr, const GooCa PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6058,15 +6333,15 @@ _wrap_GooCanvasItem__proxy_do_paint(GooCanvasItem *self, cairo_t*cr, const GooCa pyg_gil_state_release(__py_state); return; } - py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL); + py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL); py_bounds = pygoo_canvas_bounds_new(bounds); py_scale = PyFloat_FromDouble(scale); - + py_args = PyTuple_New(3); PyTuple_SET_ITEM(py_args, 0, py_cr); PyTuple_SET_ITEM(py_args, 1, py_bounds); PyTuple_SET_ITEM(py_args, 2, py_scale); - + py_method = PyObject_GetAttrString(py_self, "do_paint"); if (!py_method) { if (PyErr_Occurred()) @@ -6097,8 +6372,8 @@ _wrap_GooCanvasItem__proxy_do_paint(GooCanvasItem *self, cairo_t*cr, const GooCa pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -6117,7 +6392,7 @@ _wrap_GooCanvasItem__proxy_do_get_requested_area(GooCanvasItem *self, cairo_t*cr PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6126,13 +6401,13 @@ _wrap_GooCanvasItem__proxy_do_get_requested_area(GooCanvasItem *self, cairo_t*cr pyg_gil_state_release(__py_state); return FALSE; } - py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL); + py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL); py_requested_area = pygoo_canvas_bounds_new(requested_area); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_cr); PyTuple_SET_ITEM(py_args, 1, py_requested_area); - + py_method = PyObject_GetAttrString(py_self, "do_get_requested_area"); if (!py_method) { if (PyErr_Occurred()) @@ -6164,15 +6439,15 @@ _wrap_GooCanvasItem__proxy_do_get_requested_area(GooCanvasItem *self, cairo_t*cr pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -6188,7 +6463,7 @@ _wrap_GooCanvasItem__proxy_do_allocate_area(GooCanvasItem *self, cairo_t*cr, con PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6197,19 +6472,19 @@ _wrap_GooCanvasItem__proxy_do_allocate_area(GooCanvasItem *self, cairo_t*cr, con pyg_gil_state_release(__py_state); return; } - py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL); + py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL); py_requested_area = pygoo_canvas_bounds_new(requested_area); py_allocated_area = pygoo_canvas_bounds_new(allocated_area); py_x_offset = PyFloat_FromDouble(x_offset); py_y_offset = PyFloat_FromDouble(y_offset); - + py_args = PyTuple_New(5); PyTuple_SET_ITEM(py_args, 0, py_cr); PyTuple_SET_ITEM(py_args, 1, py_requested_area); PyTuple_SET_ITEM(py_args, 2, py_allocated_area); PyTuple_SET_ITEM(py_args, 3, py_x_offset); PyTuple_SET_ITEM(py_args, 4, py_y_offset); - + py_method = PyObject_GetAttrString(py_self, "do_allocate_area"); if (!py_method) { if (PyErr_Occurred()) @@ -6240,8 +6515,8 @@ _wrap_GooCanvasItem__proxy_do_allocate_area(GooCanvasItem *self, cairo_t*cr, con pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -6256,7 +6531,7 @@ _wrap_GooCanvasItem__proxy_do_get_style(GooCanvasItem *self) GooCanvasStyle* retval; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6265,8 +6540,8 @@ _wrap_GooCanvasItem__proxy_do_get_style(GooCanvasItem *self) pyg_gil_state_release(__py_state); return NULL; } - - + + py_method = PyObject_GetAttrString(py_self, "do_get_style"); if (!py_method) { if (PyErr_Occurred()) @@ -6305,13 +6580,13 @@ _wrap_GooCanvasItem__proxy_do_get_style(GooCanvasItem *self) } retval = (GooCanvasStyle*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -6323,7 +6598,7 @@ _wrap_GooCanvasItem__proxy_do_set_style(GooCanvasItem *self, GooCanvasStyle*styl PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6338,10 +6613,10 @@ _wrap_GooCanvasItem__proxy_do_set_style(GooCanvasItem *self, GooCanvasStyle*styl Py_INCREF(Py_None); py_style = Py_None; } - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_style); - + py_method = PyObject_GetAttrString(py_self, "do_set_style"); if (!py_method) { if (PyErr_Occurred()) @@ -6372,8 +6647,8 @@ _wrap_GooCanvasItem__proxy_do_set_style(GooCanvasItem *self, GooCanvasStyle*styl pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -6389,7 +6664,7 @@ _wrap_GooCanvasItem__proxy_do_is_visible(GooCanvasItem *self) PyObject *py_main_retval; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6398,8 +6673,8 @@ _wrap_GooCanvasItem__proxy_do_is_visible(GooCanvasItem *self) pyg_gil_state_release(__py_state); return FALSE; } - - + + py_method = PyObject_GetAttrString(py_self, "do_is_visible"); if (!py_method) { if (PyErr_Occurred()) @@ -6428,14 +6703,14 @@ _wrap_GooCanvasItem__proxy_do_is_visible(GooCanvasItem *self) pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gdouble @@ -6449,7 +6724,7 @@ _wrap_GooCanvasItem__proxy_do_get_requested_height(GooCanvasItem *self, cairo_t* PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6458,13 +6733,13 @@ _wrap_GooCanvasItem__proxy_do_get_requested_height(GooCanvasItem *self, cairo_t* pyg_gil_state_release(__py_state); return -G_MAXFLOAT; } - py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL); + py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL); py_width = PyFloat_FromDouble(width); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_cr); PyTuple_SET_ITEM(py_args, 1, py_width); - + py_method = PyObject_GetAttrString(py_self, "do_get_requested_height"); if (!py_method) { if (PyErr_Occurred()) @@ -6496,14 +6771,14 @@ _wrap_GooCanvasItem__proxy_do_get_requested_height(GooCanvasItem *self, cairo_t* pyg_gil_state_release(__py_state); return -G_MAXFLOAT; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static GooCanvasItemModel* @@ -6514,7 +6789,7 @@ _wrap_GooCanvasItem__proxy_do_get_model(GooCanvasItem *self) GooCanvasItemModel* retval; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6523,8 +6798,8 @@ _wrap_GooCanvasItem__proxy_do_get_model(GooCanvasItem *self) pyg_gil_state_release(__py_state); return NULL; } - - + + py_method = PyObject_GetAttrString(py_self, "do_get_model"); if (!py_method) { if (PyErr_Occurred()) @@ -6563,13 +6838,13 @@ _wrap_GooCanvasItem__proxy_do_get_model(GooCanvasItem *self) } retval = (GooCanvasItemModel*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -6581,7 +6856,7 @@ _wrap_GooCanvasItem__proxy_do_set_model(GooCanvasItem *self, GooCanvasItemModel* PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6596,10 +6871,10 @@ _wrap_GooCanvasItem__proxy_do_set_model(GooCanvasItem *self, GooCanvasItemModel* Py_INCREF(Py_None); py_model = Py_None; } - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_model); - + py_method = PyObject_GetAttrString(py_self, "do_set_model"); if (!py_method) { if (PyErr_Occurred()) @@ -6630,8 +6905,8 @@ _wrap_GooCanvasItem__proxy_do_set_model(GooCanvasItem *self, GooCanvasItemModel* pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -6650,7 +6925,7 @@ _wrap_GooCanvasItem__proxy_do_enter_notify_event(GooCanvasItem *self, GooCanvasI PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6666,11 +6941,11 @@ _wrap_GooCanvasItem__proxy_do_enter_notify_event(GooCanvasItem *self, GooCanvasI py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_enter_notify_event"); if (!py_method) { if (PyErr_Occurred()) @@ -6702,15 +6977,15 @@ _wrap_GooCanvasItem__proxy_do_enter_notify_event(GooCanvasItem *self, GooCanvasI pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gboolean @@ -6725,7 +7000,7 @@ _wrap_GooCanvasItem__proxy_do_leave_notify_event(GooCanvasItem *self, GooCanvasI PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6741,11 +7016,11 @@ _wrap_GooCanvasItem__proxy_do_leave_notify_event(GooCanvasItem *self, GooCanvasI py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_leave_notify_event"); if (!py_method) { if (PyErr_Occurred()) @@ -6777,15 +7052,15 @@ _wrap_GooCanvasItem__proxy_do_leave_notify_event(GooCanvasItem *self, GooCanvasI pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gboolean @@ -6800,7 +7075,7 @@ _wrap_GooCanvasItem__proxy_do_motion_notify_event(GooCanvasItem *self, GooCanvas PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6816,11 +7091,11 @@ _wrap_GooCanvasItem__proxy_do_motion_notify_event(GooCanvasItem *self, GooCanvas py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_motion_notify_event"); if (!py_method) { if (PyErr_Occurred()) @@ -6852,15 +7127,15 @@ _wrap_GooCanvasItem__proxy_do_motion_notify_event(GooCanvasItem *self, GooCanvas pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gboolean @@ -6875,7 +7150,7 @@ _wrap_GooCanvasItem__proxy_do_button_press_event(GooCanvasItem *self, GooCanvasI PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6891,11 +7166,11 @@ _wrap_GooCanvasItem__proxy_do_button_press_event(GooCanvasItem *self, GooCanvasI py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_button_press_event"); if (!py_method) { if (PyErr_Occurred()) @@ -6927,15 +7202,15 @@ _wrap_GooCanvasItem__proxy_do_button_press_event(GooCanvasItem *self, GooCanvasI pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gboolean @@ -6950,7 +7225,7 @@ _wrap_GooCanvasItem__proxy_do_button_release_event(GooCanvasItem *self, GooCanva PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -6966,11 +7241,11 @@ _wrap_GooCanvasItem__proxy_do_button_release_event(GooCanvasItem *self, GooCanva py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_button_release_event"); if (!py_method) { if (PyErr_Occurred()) @@ -7002,15 +7277,15 @@ _wrap_GooCanvasItem__proxy_do_button_release_event(GooCanvasItem *self, GooCanva pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gboolean @@ -7025,7 +7300,7 @@ _wrap_GooCanvasItem__proxy_do_focus_in_event(GooCanvasItem *self, GooCanvasItem* PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -7041,11 +7316,11 @@ _wrap_GooCanvasItem__proxy_do_focus_in_event(GooCanvasItem *self, GooCanvasItem* py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_focus_in_event"); if (!py_method) { if (PyErr_Occurred()) @@ -7077,15 +7352,15 @@ _wrap_GooCanvasItem__proxy_do_focus_in_event(GooCanvasItem *self, GooCanvasItem* pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gboolean @@ -7100,7 +7375,7 @@ _wrap_GooCanvasItem__proxy_do_focus_out_event(GooCanvasItem *self, GooCanvasItem PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -7116,11 +7391,11 @@ _wrap_GooCanvasItem__proxy_do_focus_out_event(GooCanvasItem *self, GooCanvasItem py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_focus_out_event"); if (!py_method) { if (PyErr_Occurred()) @@ -7152,15 +7427,15 @@ _wrap_GooCanvasItem__proxy_do_focus_out_event(GooCanvasItem *self, GooCanvasItem pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gboolean @@ -7175,7 +7450,7 @@ _wrap_GooCanvasItem__proxy_do_key_press_event(GooCanvasItem *self, GooCanvasItem PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -7191,11 +7466,11 @@ _wrap_GooCanvasItem__proxy_do_key_press_event(GooCanvasItem *self, GooCanvasItem py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_key_press_event"); if (!py_method) { if (PyErr_Occurred()) @@ -7227,15 +7502,15 @@ _wrap_GooCanvasItem__proxy_do_key_press_event(GooCanvasItem *self, GooCanvasItem pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gboolean @@ -7250,7 +7525,7 @@ _wrap_GooCanvasItem__proxy_do_key_release_event(GooCanvasItem *self, GooCanvasIt PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -7266,11 +7541,11 @@ _wrap_GooCanvasItem__proxy_do_key_release_event(GooCanvasItem *self, GooCanvasIt py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_key_release_event"); if (!py_method) { if (PyErr_Occurred()) @@ -7302,15 +7577,15 @@ _wrap_GooCanvasItem__proxy_do_key_release_event(GooCanvasItem *self, GooCanvasIt pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static gboolean @@ -7325,7 +7600,7 @@ _wrap_GooCanvasItem__proxy_do_grab_broken_event(GooCanvasItem *self, GooCanvasIt PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -7341,11 +7616,11 @@ _wrap_GooCanvasItem__proxy_do_grab_broken_event(GooCanvasItem *self, GooCanvasIt py_target = Py_None; } py_event = pyg_boxed_new(GDK_TYPE_EVENT, event, FALSE, FALSE); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_target); PyTuple_SET_ITEM(py_args, 1, py_event); - + py_method = PyObject_GetAttrString(py_self, "do_grab_broken_event"); if (!py_method) { if (PyErr_Occurred()) @@ -7377,15 +7652,15 @@ _wrap_GooCanvasItem__proxy_do_grab_broken_event(GooCanvasItem *self, GooCanvasIt pyg_gil_state_release(__py_state); return FALSE; } - + retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE; - + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } @@ -7722,9 +7997,9 @@ _wrap_goo_canvas_item_model_get_n_children(PyGObject *self) { int ret; - + ret = goo_canvas_item_model_get_n_children(GOO_CANVAS_ITEM_MODEL(self->obj)); - + return PyInt_FromLong(ret); } @@ -7737,9 +8012,9 @@ _wrap_goo_canvas_item_model_get_child(PyGObject *self, PyObject *args, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwargs,"i:GooCanvasItemModel.get_child", kwlist, &child_num)) return NULL; - + ret = goo_canvas_item_model_get_child(GOO_CANVAS_ITEM_MODEL(self->obj), child_num); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -7753,9 +8028,9 @@ _wrap_goo_canvas_item_model_add_child(PyGObject *self, PyObject *args, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!i:GooCanvasItemModel.add_child", kwlist, &PyGooCanvasItemModel_Type, &child, &position)) return NULL; - + goo_canvas_item_model_add_child(GOO_CANVAS_ITEM_MODEL(self->obj), GOO_CANVAS_ITEM_MODEL(child->obj), position); - + Py_INCREF(Py_None); return Py_None; } @@ -7768,9 +8043,9 @@ _wrap_goo_canvas_item_model_move_child(PyGObject *self, PyObject *args, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwargs,"ii:GooCanvasItemModel.move_child", kwlist, &old_position, &new_position)) return NULL; - + goo_canvas_item_model_move_child(GOO_CANVAS_ITEM_MODEL(self->obj), old_position, new_position); - + Py_INCREF(Py_None); return Py_None; } @@ -7783,9 +8058,9 @@ _wrap_goo_canvas_item_model_remove_child(PyGObject *self, PyObject *args, PyObje if (!PyArg_ParseTupleAndKeywords(args, kwargs,"i:GooCanvasItemModel.remove_child", kwlist, &child_num)) return NULL; - + goo_canvas_item_model_remove_child(GOO_CANVAS_ITEM_MODEL(self->obj), child_num); - + Py_INCREF(Py_None); return Py_None; } @@ -7799,13 +8074,132 @@ _wrap_goo_canvas_item_model_find_child(PyGObject *self, PyObject *args, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItemModel.find_child", kwlist, &PyGooCanvasItemModel_Type, &child)) return NULL; - + ret = goo_canvas_item_model_find_child(GOO_CANVAS_ITEM_MODEL(self->obj), GOO_CANVAS_ITEM_MODEL(child->obj)); - + return PyInt_FromLong(ret); } -#line 1084 "goocanvas.override" +#line 1826 "goocanvas.override" +static PyObject * +_wrap_goo_canvas_item_model_get_child_property(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "child", "property", NULL }; + PyGObject *pychild; + gchar *property_name; + GooCanvasItemModel *item, *child; + GObjectClass *class; + GParamSpec *pspec; + GValue value = { 0, } ; + PyObject *ret; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!s:GooCanvasItemModel.get_child_property", + kwlist, &PyGooCanvasItemModel_Type, &pychild, + &property_name)) { + return NULL; + } + + item = GOO_CANVAS_ITEM_MODEL(self->obj); + child = GOO_CANVAS_ITEM_MODEL(pychild->obj); + + if (goo_canvas_item_model_find_child(item, child) == -1) { + PyErr_SetString(PyExc_TypeError, + "first argument must be a child"); + return NULL; + } + + class = G_OBJECT_GET_CLASS(item); + pspec = goo_canvas_item_model_class_find_child_property(class, property_name); + if (!pspec) { + gchar buf[512]; + g_snprintf(buf, sizeof(buf), + "item model does not support property `%s'", + property_name); + + PyErr_SetString(PyExc_TypeError, buf); + return NULL; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + goo_canvas_item_model_get_child_property(item, + child, + property_name, + &value); + + ret = pyg_value_as_pyobject(&value, TRUE); + g_value_unset(&value); + + return ret; +} + +#line 8241 "goocanvas.c" + + +#line 1768 "goocanvas.override" +static PyObject * +_wrap_goo_canvas_item_model_set_child_property(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "child", "property", "value", NULL }; + gchar *property_name; + PyGObject *pychild; + GooCanvasItemModel *item, *child; + PyGObject *pyvalue; + GObjectClass *class; + GParamSpec *pspec; + GValue value = { 0, } ; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!sO:GooCanvasItemModel.set_child_property", + kwlist, + &PyGooCanvasItemModel_Type, &pychild, + &property_name, &pyvalue)) { + return NULL; + } + + item = GOO_CANVAS_ITEM_MODEL(self->obj); + child = GOO_CANVAS_ITEM_MODEL(pychild->obj); + + if (goo_canvas_item_model_find_child(item, child) == -1) { + PyErr_SetString(PyExc_TypeError, + "first argument must be a child"); + return NULL; + } + + class = G_OBJECT_GET_CLASS(self->obj); + pspec = goo_canvas_item_model_class_find_child_property(class, property_name); + if (!pspec) { + gchar buf[512]; + g_snprintf(buf, sizeof(buf), + "item model does not support property `%s'", + property_name); + PyErr_SetString(PyExc_TypeError, buf); + + return NULL; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + pyg_value_from_pyobject(&value, (PyObject*)pyvalue); + + goo_canvas_item_model_set_child_property(item, + child, + property_name, + &value); + g_value_unset(&value); + Py_INCREF(Py_None); + return Py_None; +} + +#line 8301 "goocanvas.c" + + +#line 1087 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_model_get_child_properties(PyGObject *self, PyObject *args) { @@ -7887,10 +8281,10 @@ _wrap_goo_canvas_item_model_get_child_properties(PyGObject *self, PyObject *args return tuple; } -#line 7891 "goocanvas.c" +#line 8386 "goocanvas.c" -#line 1003 "goocanvas.override" +#line 1006 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_model_set_child_properties(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -7970,7 +8364,7 @@ _wrap_goo_canvas_item_model_set_child_properties(PyGObject *self, PyObject *args return Py_None; } -#line 7974 "goocanvas.c" +#line 8469 "goocanvas.c" static PyObject * @@ -7978,9 +8372,9 @@ _wrap_goo_canvas_item_model_get_parent(PyGObject *self) { GooCanvasItemModel *ret; - + ret = goo_canvas_item_model_get_parent(GOO_CANVAS_ITEM_MODEL(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -7993,9 +8387,9 @@ _wrap_goo_canvas_item_model_set_parent(PyGObject *self, PyObject *args, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItemModel.set_parent", kwlist, &PyGooCanvasItemModel_Type, &parent)) return NULL; - + goo_canvas_item_model_set_parent(GOO_CANVAS_ITEM_MODEL(self->obj), GOO_CANVAS_ITEM_MODEL(parent->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -8003,9 +8397,9 @@ _wrap_goo_canvas_item_model_set_parent(PyGObject *self, PyObject *args, PyObject static PyObject * _wrap_goo_canvas_item_model_remove(PyGObject *self) { - + goo_canvas_item_model_remove(GOO_CANVAS_ITEM_MODEL(self->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -8015,9 +8409,9 @@ _wrap_goo_canvas_item_model_is_container(PyGObject *self) { int ret; - + ret = goo_canvas_item_model_is_container(GOO_CANVAS_ITEM_MODEL(self->obj)); - + return PyBool_FromLong(ret); } @@ -8030,9 +8424,9 @@ _wrap_goo_canvas_item_model_raise(PyGObject *self, PyObject *args, PyObject *kwa if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItemModel.raise", kwlist, &PyGooCanvasItemModel_Type, &above)) return NULL; - + goo_canvas_item_model_raise(GOO_CANVAS_ITEM_MODEL(self->obj), GOO_CANVAS_ITEM_MODEL(above->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -8045,14 +8439,14 @@ _wrap_goo_canvas_item_model_lower(PyGObject *self, PyObject *args, PyObject *kwa if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItemModel.lower", kwlist, &PyGooCanvasItemModel_Type, &below)) return NULL; - + goo_canvas_item_model_lower(GOO_CANVAS_ITEM_MODEL(self->obj), GOO_CANVAS_ITEM_MODEL(below->obj)); - + Py_INCREF(Py_None); return Py_None; } -#line 1566 "goocanvas.override" +#line 1569 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_model_get_transform(PyGObject *self) { @@ -8072,26 +8466,52 @@ _wrap_goo_canvas_item_model_get_transform(PyGObject *self) return matrix; } -#line 8076 "goocanvas.c" +#line 8571 "goocanvas.c" +#line 2006 "goocanvas.override" static PyObject * -_wrap_goo_canvas_item_model_set_transform(PyGObject *self, PyObject *args, PyObject *kwargs) +_wrap_goo_canvas_item_model_set_transform(PyGObject *self, + PyObject *args, + PyObject *kwargs) { static char *kwlist[] = { "matrix", NULL }; PyObject *py_matrix; - cairo_matrix_t *matrix; + cairo_matrix_t *matrix = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O:GooCanvasItemModel.set_transform", kwlist, &py_matrix)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:GooCanvasItemModel.set_transform", + kwlist, &py_matrix)) return NULL; - matrix = &((PycairoMatrix*)(py_matrix))->matrix; - - goo_canvas_item_model_set_transform(GOO_CANVAS_ITEM_MODEL(self->obj), matrix); - + + if (py_matrix && (py_matrix != Py_None)) + matrix = &((PycairoMatrix*)(py_matrix))->matrix; + + goo_canvas_item_model_set_transform(GOO_CANVAS_ITEM_MODEL(self->obj), + matrix); + Py_INCREF(Py_None); return Py_None; } +#line 8599 "goocanvas.c" + + +#line 1640 "goocanvas.override" +static PyObject * +_wrap_goo_canvas_item_model_get_simple_transform(PyGObject *self) +{ + gdouble x, y, scale, rotation; + + goo_canvas_item_model_get_simple_transform(GOO_CANVAS_ITEM_MODEL(self->obj), + &x, &y, &scale, &rotation); + + return Py_BuildValue("dddd", x, y, scale, rotation); +} + +#line 8614 "goocanvas.c" + + static PyObject * _wrap_goo_canvas_item_model_set_simple_transform(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -8100,9 +8520,9 @@ _wrap_goo_canvas_item_model_set_simple_transform(PyGObject *self, PyObject *args if (!PyArg_ParseTupleAndKeywords(args, kwargs,"dddd:GooCanvasItemModel.set_simple_transform", kwlist, &x, &y, &scale, &rotation)) return NULL; - + goo_canvas_item_model_set_simple_transform(GOO_CANVAS_ITEM_MODEL(self->obj), x, y, scale, rotation); - + Py_INCREF(Py_None); return Py_None; } @@ -8115,9 +8535,9 @@ _wrap_goo_canvas_item_model_translate(PyGObject *self, PyObject *args, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwargs,"dd:GooCanvasItemModel.translate", kwlist, &tx, &ty)) return NULL; - + goo_canvas_item_model_translate(GOO_CANVAS_ITEM_MODEL(self->obj), tx, ty); - + Py_INCREF(Py_None); return Py_None; } @@ -8130,9 +8550,9 @@ _wrap_goo_canvas_item_model_scale(PyGObject *self, PyObject *args, PyObject *kwa if (!PyArg_ParseTupleAndKeywords(args, kwargs,"dd:GooCanvasItemModel.scale", kwlist, &sx, &sy)) return NULL; - + goo_canvas_item_model_scale(GOO_CANVAS_ITEM_MODEL(self->obj), sx, sy); - + Py_INCREF(Py_None); return Py_None; } @@ -8145,9 +8565,9 @@ _wrap_goo_canvas_item_model_rotate(PyGObject *self, PyObject *args, PyObject *kw if (!PyArg_ParseTupleAndKeywords(args, kwargs,"ddd:GooCanvasItemModel.rotate", kwlist, °rees, &cx, &cy)) return NULL; - + goo_canvas_item_model_rotate(GOO_CANVAS_ITEM_MODEL(self->obj), degrees, cx, cy); - + Py_INCREF(Py_None); return Py_None; } @@ -8160,9 +8580,9 @@ _wrap_goo_canvas_item_model_skew_x(PyGObject *self, PyObject *args, PyObject *kw if (!PyArg_ParseTupleAndKeywords(args, kwargs,"ddd:GooCanvasItemModel.skew_x", kwlist, °rees, &cx, &cy)) return NULL; - + goo_canvas_item_model_skew_x(GOO_CANVAS_ITEM_MODEL(self->obj), degrees, cx, cy); - + Py_INCREF(Py_None); return Py_None; } @@ -8175,9 +8595,9 @@ _wrap_goo_canvas_item_model_skew_y(PyGObject *self, PyObject *args, PyObject *kw if (!PyArg_ParseTupleAndKeywords(args, kwargs,"ddd:GooCanvasItemModel.skew_y", kwlist, °rees, &cx, &cy)) return NULL; - + goo_canvas_item_model_skew_y(GOO_CANVAS_ITEM_MODEL(self->obj), degrees, cx, cy); - + Py_INCREF(Py_None); return Py_None; } @@ -8187,9 +8607,9 @@ _wrap_goo_canvas_item_model_get_style(PyGObject *self) { GooCanvasStyle *ret; - + ret = goo_canvas_item_model_get_style(GOO_CANVAS_ITEM_MODEL(self->obj)); - + /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } @@ -8202,9 +8622,9 @@ _wrap_goo_canvas_item_model_set_style(PyGObject *self, PyObject *args, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:GooCanvasItemModel.set_style", kwlist, &PyGooCanvasStyle_Type, &style)) return NULL; - + goo_canvas_item_model_set_style(GOO_CANVAS_ITEM_MODEL(self->obj), GOO_CANVAS_STYLE(style->obj)); - + Py_INCREF(Py_None); return Py_None; } @@ -8222,9 +8642,9 @@ _wrap_goo_canvas_item_model_animate(PyGObject *self, PyObject *args, PyObject *k return NULL; if (pyg_enum_get_value(GOO_TYPE_CANVAS_ANIMATE_TYPE, py_type, (gpointer)&type)) return NULL; - + goo_canvas_item_model_animate(GOO_CANVAS_ITEM_MODEL(self->obj), x, y, scale, degrees, absolute, duration, step_time, type); - + Py_INCREF(Py_None); return Py_None; } @@ -8232,14 +8652,14 @@ _wrap_goo_canvas_item_model_animate(PyGObject *self, PyObject *args, PyObject *k static PyObject * _wrap_goo_canvas_item_model_stop_animation(PyGObject *self) { - + goo_canvas_item_model_stop_animation(GOO_CANVAS_ITEM_MODEL(self->obj)); - + Py_INCREF(Py_None); return Py_None; } -#line 1208 "goocanvas.override" +#line 1211 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_model_find_child_property (PyObject *cls, PyObject *args, @@ -8279,10 +8699,10 @@ _wrap_goo_canvas_item_model_find_child_property (PyObject *cls, return pyg_param_spec_new(pspec); } -#line 8283 "goocanvas.c" +#line 8804 "goocanvas.c" -#line 1291 "goocanvas.override" +#line 1294 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_model_list_child_properties (PyObject *cls, PyObject *args, @@ -8323,10 +8743,10 @@ _wrap_goo_canvas_item_model_list_child_properties (PyObject *cls, return list; } -#line 8327 "goocanvas.c" +#line 8848 "goocanvas.c" -#line 1385 "goocanvas.override" +#line 1388 "goocanvas.override" static PyObject * _wrap_goo_canvas_item_model_install_child_property (PyObject *cls, PyObject *args, @@ -8377,7 +8797,7 @@ _wrap_goo_canvas_item_model_install_child_property (PyObject *cls, return Py_None; } -#line 8381 "goocanvas.c" +#line 8902 "goocanvas.c" static PyObject * @@ -8732,6 +9152,10 @@ static const PyMethodDef _PyGooCanvasItemModel_methods[] = { NULL }, { "find_child", (PyCFunction)_wrap_goo_canvas_item_model_find_child, METH_VARARGS|METH_KEYWORDS, NULL }, + { "get_child_property", (PyCFunction)_wrap_goo_canvas_item_model_get_child_property, METH_VARARGS, + NULL }, + { "set_child_property", (PyCFunction)_wrap_goo_canvas_item_model_set_child_property, METH_VARARGS|METH_KEYWORDS, + NULL }, { "get_child_properties", (PyCFunction)_wrap_goo_canvas_item_model_get_child_properties, METH_VARARGS, NULL }, { "set_child_properties", (PyCFunction)_wrap_goo_canvas_item_model_set_child_properties, METH_VARARGS|METH_KEYWORDS, @@ -8752,6 +9176,8 @@ static const PyMethodDef _PyGooCanvasItemModel_methods[] = { NULL }, { "set_transform", (PyCFunction)_wrap_goo_canvas_item_model_set_transform, METH_VARARGS|METH_KEYWORDS, NULL }, + { "get_simple_transform", (PyCFunction)_wrap_goo_canvas_item_model_get_simple_transform, METH_NOARGS, + NULL }, { "set_simple_transform", (PyCFunction)_wrap_goo_canvas_item_model_set_simple_transform, METH_VARARGS|METH_KEYWORDS, NULL }, { "translate", (PyCFunction)_wrap_goo_canvas_item_model_translate, METH_VARARGS|METH_KEYWORDS, @@ -8866,7 +9292,7 @@ _wrap_GooCanvasItemModel__proxy_do_get_n_children(GooCanvasItemModel *self) gint retval; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -8875,8 +9301,8 @@ _wrap_GooCanvasItemModel__proxy_do_get_n_children(GooCanvasItemModel *self) pyg_gil_state_release(__py_state); return -G_MAXINT; } - - + + py_method = PyObject_GetAttrString(py_self, "do_get_n_children"); if (!py_method) { if (PyErr_Occurred()) @@ -8905,13 +9331,13 @@ _wrap_GooCanvasItemModel__proxy_do_get_n_children(GooCanvasItemModel *self) pyg_gil_state_release(__py_state); return -G_MAXINT; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static GooCanvasItemModel* @@ -8924,7 +9350,7 @@ _wrap_GooCanvasItemModel__proxy_do_get_child(GooCanvasItemModel *self, gint chil PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -8934,10 +9360,10 @@ _wrap_GooCanvasItemModel__proxy_do_get_child(GooCanvasItemModel *self, gint chil return NULL; } py_child_num = PyInt_FromLong(child_num); - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_child_num); - + py_method = PyObject_GetAttrString(py_self, "do_get_child"); if (!py_method) { if (PyErr_Occurred()) @@ -8980,14 +9406,14 @@ _wrap_GooCanvasItemModel__proxy_do_get_child(GooCanvasItemModel *self, gint chil } retval = (GooCanvasItemModel*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -9000,7 +9426,7 @@ _wrap_GooCanvasItemModel__proxy_do_add_child(GooCanvasItemModel *self, GooCanvas PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9016,11 +9442,11 @@ _wrap_GooCanvasItemModel__proxy_do_add_child(GooCanvasItemModel *self, GooCanvas py_child = Py_None; } py_position = PyInt_FromLong(position); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_child); PyTuple_SET_ITEM(py_args, 1, py_position); - + py_method = PyObject_GetAttrString(py_self, "do_add_child"); if (!py_method) { if (PyErr_Occurred()) @@ -9051,8 +9477,8 @@ _wrap_GooCanvasItemModel__proxy_do_add_child(GooCanvasItemModel *self, GooCanvas pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -9069,7 +9495,7 @@ _wrap_GooCanvasItemModel__proxy_do_move_child(GooCanvasItemModel *self, gint old PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9080,11 +9506,11 @@ _wrap_GooCanvasItemModel__proxy_do_move_child(GooCanvasItemModel *self, gint old } py_old_position = PyInt_FromLong(old_position); py_new_position = PyInt_FromLong(new_position); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_old_position); PyTuple_SET_ITEM(py_args, 1, py_new_position); - + py_method = PyObject_GetAttrString(py_self, "do_move_child"); if (!py_method) { if (PyErr_Occurred()) @@ -9115,8 +9541,8 @@ _wrap_GooCanvasItemModel__proxy_do_move_child(GooCanvasItemModel *self, gint old pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -9132,7 +9558,7 @@ _wrap_GooCanvasItemModel__proxy_do_remove_child(GooCanvasItemModel *self, gint c PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9142,10 +9568,10 @@ _wrap_GooCanvasItemModel__proxy_do_remove_child(GooCanvasItemModel *self, gint c return; } py_child_num = PyInt_FromLong(child_num); - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_child_num); - + py_method = PyObject_GetAttrString(py_self, "do_remove_child"); if (!py_method) { if (PyErr_Occurred()) @@ -9176,8 +9602,8 @@ _wrap_GooCanvasItemModel__proxy_do_remove_child(GooCanvasItemModel *self, gint c pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -9192,7 +9618,7 @@ _wrap_GooCanvasItemModel__proxy_do_get_parent(GooCanvasItemModel *self) GooCanvasItemModel* retval; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9201,8 +9627,8 @@ _wrap_GooCanvasItemModel__proxy_do_get_parent(GooCanvasItemModel *self) pyg_gil_state_release(__py_state); return NULL; } - - + + py_method = PyObject_GetAttrString(py_self, "do_get_parent"); if (!py_method) { if (PyErr_Occurred()) @@ -9241,13 +9667,13 @@ _wrap_GooCanvasItemModel__proxy_do_get_parent(GooCanvasItemModel *self) } retval = (GooCanvasItemModel*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -9259,7 +9685,7 @@ _wrap_GooCanvasItemModel__proxy_do_set_parent(GooCanvasItemModel *self, GooCanva PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9274,10 +9700,10 @@ _wrap_GooCanvasItemModel__proxy_do_set_parent(GooCanvasItemModel *self, GooCanva Py_INCREF(Py_None); py_parent = Py_None; } - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_parent); - + py_method = PyObject_GetAttrString(py_self, "do_set_parent"); if (!py_method) { if (PyErr_Occurred()) @@ -9308,8 +9734,8 @@ _wrap_GooCanvasItemModel__proxy_do_set_parent(GooCanvasItemModel *self, GooCanva pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -9324,7 +9750,7 @@ _wrap_GooCanvasItemModel__proxy_do_get_style(GooCanvasItemModel *self) GooCanvasStyle* retval; PyObject *py_retval; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9333,8 +9759,8 @@ _wrap_GooCanvasItemModel__proxy_do_get_style(GooCanvasItemModel *self) pyg_gil_state_release(__py_state); return NULL; } - - + + py_method = PyObject_GetAttrString(py_self, "do_get_style"); if (!py_method) { if (PyErr_Occurred()) @@ -9373,13 +9799,13 @@ _wrap_GooCanvasItemModel__proxy_do_get_style(GooCanvasItemModel *self) } retval = (GooCanvasStyle*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -9391,7 +9817,7 @@ _wrap_GooCanvasItemModel__proxy_do_set_style(GooCanvasItemModel *self, GooCanvas PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9406,10 +9832,10 @@ _wrap_GooCanvasItemModel__proxy_do_set_style(GooCanvasItemModel *self, GooCanvas Py_INCREF(Py_None); py_style = Py_None; } - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_style); - + py_method = PyObject_GetAttrString(py_self, "do_set_style"); if (!py_method) { if (PyErr_Occurred()) @@ -9440,8 +9866,8 @@ _wrap_GooCanvasItemModel__proxy_do_set_style(GooCanvasItemModel *self, GooCanvas pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -9458,7 +9884,7 @@ _wrap_GooCanvasItemModel__proxy_do_create_item(GooCanvasItemModel *self, GooCanv PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9473,10 +9899,10 @@ _wrap_GooCanvasItemModel__proxy_do_create_item(GooCanvasItemModel *self, GooCanv Py_INCREF(Py_None); py_canvas = Py_None; } - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_canvas); - + py_method = PyObject_GetAttrString(py_self, "do_create_item"); if (!py_method) { if (PyErr_Occurred()) @@ -9519,14 +9945,14 @@ _wrap_GooCanvasItemModel__proxy_do_create_item(GooCanvasItemModel *self, GooCanv } retval = (GooCanvasItem*) pygobject_get(py_retval); g_object_ref((GObject *) retval); - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); Py_DECREF(py_self); pyg_gil_state_release(__py_state); - + return retval; } static void @@ -9538,7 +9964,7 @@ _wrap_GooCanvasItemModel__proxy_do_child_added(GooCanvasItemModel *self, gint ch PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9548,10 +9974,10 @@ _wrap_GooCanvasItemModel__proxy_do_child_added(GooCanvasItemModel *self, gint ch return; } py_child_num = PyInt_FromLong(child_num); - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_child_num); - + py_method = PyObject_GetAttrString(py_self, "do_child_added"); if (!py_method) { if (PyErr_Occurred()) @@ -9582,8 +10008,8 @@ _wrap_GooCanvasItemModel__proxy_do_child_added(GooCanvasItemModel *self, gint ch pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -9600,7 +10026,7 @@ _wrap_GooCanvasItemModel__proxy_do_child_moved(GooCanvasItemModel *self, gint ol PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9611,11 +10037,11 @@ _wrap_GooCanvasItemModel__proxy_do_child_moved(GooCanvasItemModel *self, gint ol } py_old_child_num = PyInt_FromLong(old_child_num); py_new_child_num = PyInt_FromLong(new_child_num); - + py_args = PyTuple_New(2); PyTuple_SET_ITEM(py_args, 0, py_old_child_num); PyTuple_SET_ITEM(py_args, 1, py_new_child_num); - + py_method = PyObject_GetAttrString(py_self, "do_child_moved"); if (!py_method) { if (PyErr_Occurred()) @@ -9646,8 +10072,8 @@ _wrap_GooCanvasItemModel__proxy_do_child_moved(GooCanvasItemModel *self, gint ol pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -9663,7 +10089,7 @@ _wrap_GooCanvasItemModel__proxy_do_child_removed(GooCanvasItemModel *self, gint PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9673,10 +10099,10 @@ _wrap_GooCanvasItemModel__proxy_do_child_removed(GooCanvasItemModel *self, gint return; } py_child_num = PyInt_FromLong(child_num); - + py_args = PyTuple_New(1); PyTuple_SET_ITEM(py_args, 0, py_child_num); - + py_method = PyObject_GetAttrString(py_self, "do_child_removed"); if (!py_method) { if (PyErr_Occurred()) @@ -9707,8 +10133,8 @@ _wrap_GooCanvasItemModel__proxy_do_child_removed(GooCanvasItemModel *self, gint pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -9724,7 +10150,7 @@ _wrap_GooCanvasItemModel__proxy_do_changed(GooCanvasItemModel *self, gboolean re PyObject *py_retval; PyObject *py_args; PyObject *py_method; - + __py_state = pyg_gil_state_ensure(); py_self = pygobject_new((GObject *) self); if (!py_self) { @@ -9734,11 +10160,11 @@ _wrap_GooCanvasItemModel__proxy_do_changed(GooCanvasItemModel *self, gboolean re return; } py_recompute_bounds = recompute_bounds? Py_True : Py_False; - + py_args = PyTuple_New(1); Py_INCREF(py_recompute_bounds); PyTuple_SET_ITEM(py_args, 0, py_recompute_bounds); - + py_method = PyObject_GetAttrString(py_self, "do_changed"); if (!py_method) { if (PyErr_Occurred()) @@ -9769,8 +10195,8 @@ _wrap_GooCanvasItemModel__proxy_do_changed(GooCanvasItemModel *self, gboolean re pyg_gil_state_release(__py_state); return; } - - + + Py_XDECREF(py_retval); Py_DECREF(py_method); Py_DECREF(py_args); @@ -9936,7 +10362,7 @@ static const GInterfaceInfo __GooCanvasItemModel__iinfo = { /* ----------- functions ----------- */ -#line 308 "goocanvas.override" +#line 311 "goocanvas.override" static PyObject * _wrap_goo_canvas_polyline_new_line(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -10003,10 +10429,10 @@ _wrap_goo_canvas_polyline_new_line(PyGObject *self, PyObject *args, PyObject *kw return pygobject_new((GObject *)ret); } -#line 10007 "goocanvas.c" +#line 10534 "goocanvas.c" -#line 376 "goocanvas.override" +#line 379 "goocanvas.override" static PyObject * _wrap_goo_canvas_polyline_model_new_line(PyGObject *self, PyObject *args, PyObject *kwargs) { @@ -10074,7 +10500,7 @@ _wrap_goo_canvas_polyline_model_new_line(PyGObject *self, PyObject *args, PyObje return pygobject_new((GObject *)ret); } -#line 10078 "goocanvas.c" +#line 10605 "goocanvas.c" static PyObject * @@ -10087,9 +10513,9 @@ _wrap_goo_cairo_matrix_copy(PyObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O:goo_cairo_matrix_copy", kwlist, &py_matrix)) return NULL; matrix = &((PycairoMatrix*)(py_matrix))->matrix; - + ret = goo_cairo_matrix_copy(matrix); - + if (ret) return PycairoMatrix_FromMatrix(ret); else { @@ -10108,9 +10534,9 @@ _wrap_goo_cairo_matrix_free(PyObject *self, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O:goo_cairo_matrix_free", kwlist, &py_matrix)) return NULL; matrix = &((PycairoMatrix*)(py_matrix))->matrix; - + goo_cairo_matrix_free(matrix); - + Py_INCREF(Py_None); return Py_None; } @@ -10190,6 +10616,18 @@ pygoocanvas_register_classes(PyObject *d) "could not import gtk"); return ; } + if ((module = PyImport_ImportModule("gtk.gdk")) != NULL) { + _PyGdkCairoContext_Type = (PyTypeObject *)PyObject_GetAttrString(module, "CairoContext"); + if (_PyGdkCairoContext_Type == NULL) { + PyErr_SetString(PyExc_ImportError, + "cannot import name CairoContext from gtk.gdk"); + return ; + } + } else { + PyErr_SetString(PyExc_ImportError, + "could not import gtk.gdk"); + return ; + } #line 198 "goocanvas.override" @@ -10202,7 +10640,7 @@ pygoocanvas_register_classes(PyObject *d) -#line 10206 "goocanvas.c" +#line 10745 "goocanvas.c" pyg_register_boxed(d, "Points", GOO_TYPE_CANVAS_POINTS, &PyGooCanvasPoints_Type); pyg_register_boxed(d, "LineDash", GOO_TYPE_CANVAS_LINE_DASH, &PyGooCanvasLineDash_Type); pyg_register_interface(d, "Item", GOO_TYPE_CANVAS_ITEM, &PyGooCanvasItem_Type); @@ -10210,7 +10648,6 @@ pygoocanvas_register_classes(PyObject *d) pyg_register_interface(d, "ItemModel", GOO_TYPE_CANVAS_ITEM_MODEL, &PyGooCanvasItemModel_Type); pyg_register_interface_info(GOO_TYPE_CANVAS_ITEM_MODEL, &__GooCanvasItemModel__iinfo); pygobject_register_class(d, "GooCanvas", GOO_TYPE_CANVAS, &PyGooCanvas_Type, Py_BuildValue("(O)", &PyGtkContainer_Type)); - pyg_set_object_has_new_constructor(GOO_TYPE_CANVAS); pyg_register_class_init(GOO_TYPE_CANVAS, __GooCanvas_class_init); pygobject_register_class(d, "GooCanvasItemModelSimple", GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE, &PyGooCanvasItemModelSimple_Type, Py_BuildValue("(O)", &PyGObject_Type)); pyg_set_object_has_new_constructor(GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE); @@ -10225,8 +10662,6 @@ pygoocanvas_register_classes(PyObject *d) pyg_register_class_init(GOO_TYPE_CANVAS_ITEM_SIMPLE, __GooCanvasItemSimple_class_init); pygobject_register_class(d, "GooCanvasImage", GOO_TYPE_CANVAS_IMAGE, &PyGooCanvasImage_Type, Py_BuildValue("(O)", &PyGooCanvasItemSimple_Type)); pyg_set_object_has_new_constructor(GOO_TYPE_CANVAS_IMAGE); - pygobject_register_class(d, "GooCanvasSvg", GOO_TYPE_CANVAS_SVG, &PyGooCanvasSvg_Type, Py_BuildValue("(O)", &PyGooCanvasItemSimple_Type)); - pyg_set_object_has_new_constructor(GOO_TYPE_CANVAS_SVG); pygobject_register_class(d, "GooCanvasGroup", GOO_TYPE_CANVAS_GROUP, &PyGooCanvasGroup_Type, Py_BuildValue("(O)", &PyGooCanvasItemSimple_Type)); pyg_set_object_has_new_constructor(GOO_TYPE_CANVAS_GROUP); pygobject_register_class(d, "GooCanvasEllipse", GOO_TYPE_CANVAS_ELLIPSE, &PyGooCanvasEllipse_Type, Py_BuildValue("(O)", &PyGooCanvasItemSimple_Type)); diff --git a/src/boards/goocanvas.defs b/src/boards/goocanvas.defs index 863ce38..e534752 100644 --- a/src/boards/goocanvas.defs +++ b/src/boards/goocanvas.defs @@ -67,13 +67,6 @@ (gtype-id "GOO_TYPE_CANVAS_IMAGE") ) -(define-object Svg - (in-module "Goo") - (parent "GooCanvasItemSimple") - (c-name "GooCanvasSvg") - (gtype-id "GOO_TYPE_CANVAS_SVG") -) - (define-object Group (in-module "Goo") (parent "GooCanvasItemSimple") @@ -108,6 +101,9 @@ (gtype-id "GOO_TYPE_CANVAS_POINTS") (copy-func "goo_canvas_points_ref") (release-func "goo_canvas_points_unref") + (fields + ("double*" "coords") + ("int" "num_points")) ) (define-object Polyline @@ -288,6 +284,36 @@ ) ) +(define-method get_static_root_item + (of-object "GooCanvas") + (c-name "goo_canvas_get_static_root_item") + (return-type "GooCanvasItem*") +) + +(define-method set_static_root_item + (of-object "GooCanvas") + (c-name "goo_canvas_set_static_root_item") + (return-type "none") + (parameters + '("GooCanvasItem*" "item") + ) +) + +(define-method get_static_root_item_model + (of-object "GooCanvas") + (c-name "goo_canvas_get_static_root_item_model") + (return-type "GooCanvasItemModel*") +) + +(define-method set_static_root_item_model + (of-object "GooCanvas") + (c-name "goo_canvas_set_static_root_item_model") + (return-type "none") + (parameters + '("GooCanvasItemModel*" "model") + ) +) + (define-method get_item (of-object "GooCanvas") (c-name "goo_canvas_get_item") @@ -442,6 +468,16 @@ ) ) +(define-method convert_bounds_to_item_space + (of-object "GooCanvas") + (c-name "goo_canvas_convert_bounds_to_item_space") + (return-type "none") + (parameters + '("GooCanvasItem*" "item") + '("GooCanvasBounds*" "bounds") + ) +) + (define-method pointer_grab (of-object "GooCanvas") (c-name "goo_canvas_pointer_grab") @@ -530,6 +566,16 @@ ) ) +(define-method request_item_redraw + (of-object "GooCanvas") + (c-name "goo_canvas_request_item_redraw") + (return-type "none") + (parameters + '("const-GooCanvasBounds*" "bounds") + '("gboolean" "is_static") + ) +) + (define-method get_default_line_width (of-object "GooCanvas") (c-name "goo_canvas_get_default_line_width") @@ -645,6 +691,7 @@ + ;; From goocanvasgroup.h (define-function goo_canvas_group_get_type @@ -719,27 +766,6 @@ -;; From goocanvassvg.h - -(define-function goo_canvas_svg_get_type - (c-name "goo_canvas_svg_get_type") - (return-type "GType") -) - -(define-function goo_canvas_svg_new - (c-name "goo_canvas_svg_new") - (is-constructor-of "GooCanvasSvg") - (return-type "GooCanvasItem*") - (parameters - '("GooCanvasItem*" "parent") - '("RsvgHandle*" "svg_handle") - '("const-gchar*" "svg_id") - ) - (varargs #t) -) - - - ;; From goocanvasitem.h (define-function goo_canvas_item_get_type @@ -800,6 +826,28 @@ ) ) +(define-method get_child_property + (of-object "GooCanvasItem") + (c-name "goo_canvas_item_get_child_property") + (return-type "none") + (parameters + '("GooCanvasItem*" "child") + '("const-gchar*" "property_name") + '("GValue*" "value") + ) +) + +(define-method set_child_property + (of-object "GooCanvasItem") + (c-name "goo_canvas_item_set_child_property") + (return-type "none") + (parameters + '("GooCanvasItem*" "child") + '("const-gchar*" "property_name") + '("const-GValue*" "value") + ) +) + (define-method get_child_properties (of-object "GooCanvasItem") (c-name "goo_canvas_item_get_child_properties") @@ -928,6 +976,18 @@ ) ) +(define-method get_simple_transform + (of-object "GooCanvasItem") + (c-name "goo_canvas_item_get_simple_transform") + (return-type "gboolean") + (parameters + '("gdouble*" "x") + '("gdouble*" "y") + '("gdouble*" "scale") + '("gdouble*" "rotation") + ) +) + (define-method set_simple_transform (of-object "GooCanvasItem") (c-name "goo_canvas_item_set_simple_transform") @@ -1510,6 +1570,28 @@ ) ) +(define-method get_child_property + (of-object "GooCanvasItemModel") + (c-name "goo_canvas_item_model_get_child_property") + (return-type "none") + (parameters + '("GooCanvasItemModel*" "child") + '("const-gchar*" "property_name") + '("GValue*" "value") + ) +) + +(define-method set_child_property + (of-object "GooCanvasItemModel") + (c-name "goo_canvas_item_model_set_child_property") + (return-type "none") + (parameters + '("GooCanvasItemModel*" "child") + '("const-gchar*" "property_name") + '("const-GValue*" "value") + ) +) + (define-method get_child_properties (of-object "GooCanvasItemModel") (c-name "goo_canvas_item_model_get_child_properties") @@ -1613,6 +1695,18 @@ ) ) +(define-method get_simple_transform + (of-object "GooCanvasItemModel") + (c-name "goo_canvas_item_model_get_simple_transform") + (return-type "gboolean") + (parameters + '("gdouble*" "x") + '("gdouble*" "y") + '("gdouble*" "scale") + '("gdouble*" "rotation") + ) +) + (define-method set_simple_transform (of-object "GooCanvasItemModel") (c-name "goo_canvas_item_model_set_simple_transform") @@ -2306,6 +2400,16 @@ (varargs #t) ) +(define-method get_natural_extents + (of-object "GooCanvasText") + (c-name "goo_canvas_text_get_natural_extents") + (return-type "none") + (parameters + '("PangoRectangle*" "ink_rect") + '("PangoRectangle*" "logical_rect") + ) +) + (define-function goo_canvas_text_model_get_type (c-name "goo_canvas_text_model_get_type") (return-type "GType") diff --git a/src/boards/goocanvas.override b/src/boards/goocanvas.override index e382c5c..334a5ba 100644 --- a/src/boards/goocanvas.override +++ b/src/boards/goocanvas.override @@ -210,14 +210,15 @@ modulename goocanvas import gobject.GObject as PyGObject_Type import gtk.Container as PyGtkContainer_Type import gtk.Adjustment as PyGtkAdjustment_Type +import gtk.gdk.CairoContext as PyGdkCairoContext_Type %% ignore +goo_canvas_new goo_canvas_ellipse_new goo_canvas_ellipse_model_new goo_canvas_group_new goo_canvas_group_model_new -goo_canvas_svg_new goo_canvas_image_new goo_canvas_image_model_new goo_canvas_path_new @@ -649,7 +650,7 @@ _wrap_GooCanvasItem__proxy_do_update(GooCanvasItem *self, gboolean entire_tree, py_bounds = PyObject_CallMethod(py_self, "do_update", "iN", entire_tree, - PycairoContext_FromContext(cairo_reference(cr), NULL, NULL)); + PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL)); if (py_bounds) *bounds = ((PyGooCanvasBounds *) py_bounds)->bounds; else @@ -1601,3 +1602,438 @@ _wrap_goo_canvas_item_simple__get_bounds(PyGObject *self, void *closure) { return pygoo_canvas_bounds_new(&GOO_CANVAS_ITEM_SIMPLE(pygobject_get(self))->bounds); } + +%% +override goo_canvas_text_get_natural_extents noargs +static PyObject * +_wrap_goo_canvas_text_get_natural_extents(PyGObject *self) +{ + PangoRectangle ink_rect, logical_rect; + + goo_canvas_text_get_natural_extents(GOO_CANVAS_TEXT(self->obj), &ink_rect, + &logical_rect); + + return Py_BuildValue("((iiii)(iiii))", + ink_rect.x, ink_rect.y, + ink_rect.width, ink_rect.height, + logical_rect.x, logical_rect.y, + logical_rect.width, logical_rect.height); +} + +%% +override goo_canvas_item_get_simple_transform noargs +static PyObject * +_wrap_goo_canvas_item_get_simple_transform(PyGObject *self) +{ + gdouble x, y, scale, rotation; + + goo_canvas_item_get_simple_transform(GOO_CANVAS_ITEM(self->obj), &x, &y, + &scale, &rotation); + + return Py_BuildValue("dddd", x, y, scale, rotation); +} + +%% +override goo_canvas_item_model_get_simple_transform noargs +static PyObject * +_wrap_goo_canvas_item_model_get_simple_transform(PyGObject *self) +{ + gdouble x, y, scale, rotation; + + goo_canvas_item_model_get_simple_transform(GOO_CANVAS_ITEM_MODEL(self->obj), + &x, &y, &scale, &rotation); + + return Py_BuildValue("dddd", x, y, scale, rotation); +} + +%% +override goo_canvas_item_set_child_property kwargs +static PyObject * +_wrap_goo_canvas_item_set_child_property(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "child", "property", "value", NULL }; + gchar *property_name; + PyGObject *pychild; + GooCanvasItem *item, *child; + PyGObject *pyvalue; + GObjectClass *class; + GParamSpec *pspec; + GValue value = { 0, } ; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!sO:GooCanvasItem.set_child_property", + kwlist, + &PyGooCanvasItem_Type, &pychild, + &property_name, &pyvalue)) { + return NULL; + } + + item = GOO_CANVAS_ITEM(self->obj); + child = GOO_CANVAS_ITEM(pychild->obj); + + if (goo_canvas_item_find_child(item, child) == -1) { + PyErr_SetString(PyExc_TypeError, + "first argument must be a child"); + return NULL; + } + + class = G_OBJECT_GET_CLASS(self->obj); + pspec = goo_canvas_item_class_find_child_property(class, property_name); + if (!pspec) { + gchar buf[512]; + g_snprintf(buf, sizeof(buf), + "item does not support property `%s'", + property_name); + PyErr_SetString(PyExc_TypeError, buf); + + return NULL; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + pyg_value_from_pyobject(&value, (PyObject*)pyvalue); + + goo_canvas_item_set_child_property(item, + child, + property_name, + &value); + g_value_unset(&value); + Py_INCREF(Py_None); + return Py_None; +} + +%% +override goo_canvas_item_get_child_property +static PyObject * +_wrap_goo_canvas_item_get_child_property(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "child", "property", NULL }; + PyGObject *pychild; + gchar *property_name; + GooCanvasItem *item, *child; + GObjectClass *class; + GParamSpec *pspec; + GValue value = { 0, } ; + PyObject *ret; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!s:GooCanvasItem.get_child_property", + kwlist, &PyGooCanvasItem_Type, &pychild, + &property_name)) { + return NULL; + } + + item = GOO_CANVAS_ITEM(self->obj); + child = GOO_CANVAS_ITEM(pychild->obj); + + if (goo_canvas_item_find_child(item, child) == -1) { + PyErr_SetString(PyExc_TypeError, + "first argument must be a child"); + return NULL; + } + + class = G_OBJECT_GET_CLASS(item); + pspec = goo_canvas_item_class_find_child_property(class, property_name); + if (!pspec) { + gchar buf[512]; + g_snprintf(buf, sizeof(buf), + "item does not support property `%s'", + property_name); + + PyErr_SetString(PyExc_TypeError, buf); + return NULL; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + goo_canvas_item_get_child_property(item, + child, + property_name, + &value); + + ret = pyg_value_as_pyobject(&value, TRUE); + g_value_unset(&value); + + return ret; +} + +%% +override goo_canvas_item_model_set_child_property kwargs +static PyObject * +_wrap_goo_canvas_item_model_set_child_property(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "child", "property", "value", NULL }; + gchar *property_name; + PyGObject *pychild; + GooCanvasItemModel *item, *child; + PyGObject *pyvalue; + GObjectClass *class; + GParamSpec *pspec; + GValue value = { 0, } ; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!sO:GooCanvasItemModel.set_child_property", + kwlist, + &PyGooCanvasItemModel_Type, &pychild, + &property_name, &pyvalue)) { + return NULL; + } + + item = GOO_CANVAS_ITEM_MODEL(self->obj); + child = GOO_CANVAS_ITEM_MODEL(pychild->obj); + + if (goo_canvas_item_model_find_child(item, child) == -1) { + PyErr_SetString(PyExc_TypeError, + "first argument must be a child"); + return NULL; + } + + class = G_OBJECT_GET_CLASS(self->obj); + pspec = goo_canvas_item_model_class_find_child_property(class, property_name); + if (!pspec) { + gchar buf[512]; + g_snprintf(buf, sizeof(buf), + "item model does not support property `%s'", + property_name); + PyErr_SetString(PyExc_TypeError, buf); + + return NULL; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + pyg_value_from_pyobject(&value, (PyObject*)pyvalue); + + goo_canvas_item_model_set_child_property(item, + child, + property_name, + &value); + g_value_unset(&value); + Py_INCREF(Py_None); + return Py_None; +} + +%% +override goo_canvas_item_model_get_child_property +static PyObject * +_wrap_goo_canvas_item_model_get_child_property(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "child", "property", NULL }; + PyGObject *pychild; + gchar *property_name; + GooCanvasItemModel *item, *child; + GObjectClass *class; + GParamSpec *pspec; + GValue value = { 0, } ; + PyObject *ret; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!s:GooCanvasItemModel.get_child_property", + kwlist, &PyGooCanvasItemModel_Type, &pychild, + &property_name)) { + return NULL; + } + + item = GOO_CANVAS_ITEM_MODEL(self->obj); + child = GOO_CANVAS_ITEM_MODEL(pychild->obj); + + if (goo_canvas_item_model_find_child(item, child) == -1) { + PyErr_SetString(PyExc_TypeError, + "first argument must be a child"); + return NULL; + } + + class = G_OBJECT_GET_CLASS(item); + pspec = goo_canvas_item_model_class_find_child_property(class, property_name); + if (!pspec) { + gchar buf[512]; + g_snprintf(buf, sizeof(buf), + "item model does not support property `%s'", + property_name); + + PyErr_SetString(PyExc_TypeError, buf); + return NULL; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + goo_canvas_item_model_get_child_property(item, + child, + property_name, + &value); + + ret = pyg_value_as_pyobject(&value, TRUE); + g_value_unset(&value); + + return ret; +} + +%% +override-attr GooCanvasPoints.coords + +static PyObject * +_wrap_goo_canvas_points__get_coords(PyObject *self, void *closure) +{ + gdouble *coords; + int num_points, i; + PyObject *ret = Py_None; + + num_points = pyg_boxed_get(self, GooCanvasPoints)->num_points; + coords = pyg_boxed_get(self, GooCanvasPoints)->coords; + + if (num_points > 0) { + ret = PyList_New(num_points); + + for (i = 0; i < num_points; i ++) { + PyObject *py_temp = Py_BuildValue("dd", coords[2*i], coords[2*i + 1]); + PyList_SetItem(ret, i, py_temp); + } + return ret; + } + Py_INCREF(ret); + return ret; +} + +%% +override goo_canvas_item_get_requested_area kwargs +static PyObject * +_wrap_goo_canvas_item_get_requested_area(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "cr", NULL }; + int ret; + GooCanvasBounds bounds; + PycairoContext *cr; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!:GooCanvasItem.get_requested_area", + kwlist, &PycairoContext_Type, &cr)) + return NULL; + + ret = goo_canvas_item_get_requested_area(GOO_CANVAS_ITEM(self->obj), + cr->ctx, &bounds); + + return pygoo_canvas_bounds_new(&bounds); +} + +%% +override goo_canvas_item_update kwargs +static PyObject * +_wrap_goo_canvas_item_update(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "entire_tree", "cr", NULL }; + int entire_tree; + PycairoContext *cr; + GooCanvasBounds bounds; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"iO!:GooCanvasItem.update", + kwlist, &entire_tree, + &PycairoContext_Type, &cr)) + return NULL; + + goo_canvas_item_update(GOO_CANVAS_ITEM(self->obj), entire_tree, + cr->ctx, &bounds); + + return pygoo_canvas_bounds_new(&bounds); +} + +%% +override goo_canvas_item_get_transform_for_child kwargs +static PyObject * +_wrap_goo_canvas_item_get_transform_for_child(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "child", NULL }; + PyGObject *child; + int ret; + cairo_matrix_t *transform = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O!:GooCanvasItem.get_transform_for_child", + kwlist, &PyGooCanvasItem_Type, &child)) + return NULL; + + ret = goo_canvas_item_get_transform_for_child(GOO_CANVAS_ITEM(self->obj), + GOO_CANVAS_ITEM(child->obj), + transform); + + if (ret) + return PycairoMatrix_FromMatrix(transform); + else + Py_INCREF(Py_None); + return Py_None; +} + +%% +override goo_canvas_item_set_transform kwargs +static PyObject * +_wrap_goo_canvas_item_set_transform(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "matrix", NULL }; + PyObject *py_matrix; + cairo_matrix_t *matrix = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:GooCanvasItem.set_transform", + kwlist, &py_matrix)) + return NULL; + + if (py_matrix && (py_matrix != Py_None)) + matrix = &((PycairoMatrix*)(py_matrix))->matrix; + + goo_canvas_item_set_transform(GOO_CANVAS_ITEM(self->obj), matrix); + + Py_INCREF(Py_None); + return Py_None; +} + +%% +override goo_canvas_item_model_set_transform kwargs +static PyObject * +_wrap_goo_canvas_item_model_set_transform(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "matrix", NULL }; + PyObject *py_matrix; + cairo_matrix_t *matrix = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:GooCanvasItemModel.set_transform", + kwlist, &py_matrix)) + return NULL; + + if (py_matrix && (py_matrix != Py_None)) + matrix = &((PycairoMatrix*)(py_matrix))->matrix; + + goo_canvas_item_model_set_transform(GOO_CANVAS_ITEM_MODEL(self->obj), + matrix); + + Py_INCREF(Py_None); + return Py_None; +} + +%% +override goo_canvas_create_cairo_context noargs +static PyObject * +_wrap_goo_canvas_create_cairo_context(PyGObject *self) +{ + cairo_t *ret; + + ret = goo_canvas_create_cairo_context(GOO_CANVAS(self->obj)); + + cairo_reference(ret); + return PycairoContext_FromContext(ret, &PyGdkCairoContext_Type, NULL); +} diff --git a/src/boards/goocanvasmodule.c b/src/boards/goocanvasmodule.c index 95a75a8..bf19f2b 100644 --- a/src/boards/goocanvasmodule.c +++ b/src/boards/goocanvasmodule.c @@ -11,11 +11,11 @@ Pycairo_CAPI_t *Pycairo_CAPI; -void pygoocanvas_register_classes (PyObject *d); +void pygoocanvas_register_classes (PyObject *d); void pygoocanvas_add_constants(PyObject *module, const gchar *strip_prefix); extern PyMethodDef pygoocanvas_functions[]; - + static PyObject * _cairo_matrix_from_gvalue(const GValue *value) { @@ -65,9 +65,9 @@ initgoocanvas (void) m = Py_InitModule ("goocanvas", pygoocanvas_functions); d = PyModule_GetDict (m); - + init_pygobject (); - + pygoocanvas_register_classes (d); pygoocanvas_add_constants(m, "GOO_CANVAS_"); PyModule_AddObject(m, "TYPE_CAIRO_MATRIX", pyg_type_wrapper_new(GOO_TYPE_CAIRO_MATRIX)); @@ -84,7 +84,7 @@ initgoocanvas (void) PYGOOCANVAS_MAJOR_VERSION, PYGOOCANVAS_MINOR_VERSION, PYGOOCANVAS_MICRO_VERSION)); - + if (PyErr_Occurred ()) Py_FatalError ("can't initialise module goocanvas"); } diff --git a/src/goocanvas/src/goocanvas.c b/src/goocanvas/src/goocanvas.c index 2eb41b3..f59bbdf 100644 --- a/src/goocanvas/src/goocanvas.c +++ b/src/goocanvas/src/goocanvas.c @@ -105,6 +105,17 @@ #include "goocanvasmarshal.h" +#define GOO_CANVAS_GET_PRIVATE(canvas) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((canvas), GOO_TYPE_CANVAS, GooCanvasPrivate)) + +typedef struct _GooCanvasPrivate GooCanvasPrivate; +struct _GooCanvasPrivate { + GooCanvasItem *static_root_item; + GooCanvasItemModel *static_root_item_model; + gint window_x, window_y; +}; + + enum { PROP_0, @@ -125,7 +136,8 @@ enum { PROP_BACKGROUND_COLOR, PROP_BACKGROUND_COLOR_RGB, PROP_INTEGER_LAYOUT, - PROP_CLEAR_BACKGROUND + PROP_CLEAR_BACKGROUND, + PROP_REDRAW_WHEN_SCROLLED }; enum { @@ -134,6 +146,7 @@ enum { LAST_SIGNAL }; + static guint canvas_signals[LAST_SIGNAL] = { 0 }; static void goo_canvas_dispose (GObject *object); @@ -188,6 +201,11 @@ static void goo_canvas_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); +static gboolean goo_canvas_query_tooltip (GtkWidget *widget, + gint x, + gint y, + gboolean keyboard_tip, + GtkTooltip *tooltip); static void goo_canvas_set_scale_internal (GooCanvas *canvas, gdouble scale_x, @@ -201,6 +219,9 @@ static void reconfigure_canvas (GooCanvas *canvas, gboolean redraw_if_needed); static void goo_canvas_update_automatic_bounds (GooCanvas *canvas); +static void goo_canvas_convert_to_static_item_space (GooCanvas *canvas, + gdouble *x, + gdouble *y); G_DEFINE_TYPE (GooCanvas, goo_canvas, GTK_TYPE_CONTAINER) @@ -217,6 +238,8 @@ goo_canvas_class_init (GooCanvasClass *klass) GtkWidgetClass *widget_class = (GtkWidgetClass*) klass; GtkContainerClass *container_class = (GtkContainerClass*) klass; + g_type_class_add_private (gobject_class, sizeof (GooCanvasPrivate)); + gobject_class->dispose = goo_canvas_dispose; gobject_class->finalize = goo_canvas_finalize; gobject_class->get_property = goo_canvas_get_property; @@ -241,6 +264,7 @@ goo_canvas_class_init (GooCanvasClass *klass) widget_class->focus_in_event = goo_canvas_focus_in; widget_class->focus_out_event = goo_canvas_focus_out; widget_class->grab_broken_event = goo_canvas_grab_broken; + widget_class->query_tooltip = goo_canvas_query_tooltip; container_class->remove = goo_canvas_remove; container_class->forall = goo_canvas_forall; @@ -393,6 +417,13 @@ goo_canvas_class_init (GooCanvasClass *klass) TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_REDRAW_WHEN_SCROLLED, + g_param_spec_boolean ("redraw-when-scrolled", + _("Redraw When Scrolled"), + _("If the canvas is completely redrawn when scrolled, to reduce the flicker of static items"), + FALSE, + G_PARAM_READWRITE)); + /** * GooCanvas::set-scroll-adjustments * @canvas: the canvas. @@ -443,6 +474,8 @@ goo_canvas_class_init (GooCanvasClass *klass) static void goo_canvas_init (GooCanvas *canvas) { + GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas); + /* We set GTK_CAN_FOCUS by default, so it works as people expect. Though developers can turn this off if not needed for efficiency. */ GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS); @@ -455,6 +488,7 @@ goo_canvas_init (GooCanvas *canvas) canvas->crossing_event.type = GDK_LEAVE_NOTIFY; canvas->anchor = GTK_ANCHOR_NORTH_WEST; canvas->clear_background = TRUE; + canvas->redraw_when_scrolled = FALSE; /* Set the default bounds to a reasonable size. */ canvas->bounds.x1 = 0.0; @@ -485,6 +519,14 @@ goo_canvas_init (GooCanvas *canvas) time. Apps can set their own root item if required. */ canvas->root_item = goo_canvas_group_new (NULL, NULL); goo_canvas_item_set_canvas (canvas->root_item, canvas); + + priv->static_root_item = goo_canvas_group_new (NULL, NULL); + goo_canvas_item_set_canvas (priv->static_root_item, canvas); + goo_canvas_item_set_is_static (priv->static_root_item, TRUE); + priv->static_root_item_model = NULL; + + priv->window_x = 0; + priv->window_y = 0; } @@ -509,6 +551,7 @@ static void goo_canvas_dispose (GObject *object) { GooCanvas *canvas = (GooCanvas*) object; + GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas); if (canvas->model_to_item) { @@ -528,6 +571,18 @@ goo_canvas_dispose (GObject *object) canvas->root_item_model = NULL; } + if (priv->static_root_item) + { + g_object_unref (priv->static_root_item); + priv->static_root_item = NULL; + } + + if (priv->static_root_item_model) + { + g_object_unref (priv->static_root_item_model); + priv->static_root_item_model = NULL; + } + if (canvas->idle_id) { g_source_remove (canvas->idle_id); @@ -703,6 +758,9 @@ goo_canvas_get_property (GObject *object, case PROP_CLEAR_BACKGROUND: g_value_set_boolean (value, canvas->clear_background); break; + case PROP_REDRAW_WHEN_SCROLLED: + g_value_set_boolean (value, canvas->redraw_when_scrolled); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -806,6 +864,9 @@ goo_canvas_set_property (GObject *object, case PROP_CLEAR_BACKGROUND: canvas->clear_background = g_value_get_boolean (value); break; + case PROP_REDRAW_WHEN_SCROLLED: + canvas->redraw_when_scrolled = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -954,6 +1015,170 @@ goo_canvas_set_root_item (GooCanvas *canvas, /** + * goo_canvas_get_static_root_item: + * @canvas: a #GooCanvas. + * + * Gets the static root item of the canvas. + * + * Static items are exactly the same as ordinary canvas items, except that + * they do not move or change size when the canvas is scrolled or the scale + * changes. + * + * Static items are added to the static root item in exactly the same way that + * ordinary items are added to the root item. + * + * Returns: the static root item, or %NULL. + **/ +GooCanvasItem* +goo_canvas_get_static_root_item (GooCanvas *canvas) +{ + g_return_val_if_fail (GOO_IS_CANVAS (canvas), NULL); + + return GOO_CANVAS_GET_PRIVATE (canvas)->static_root_item; +} + + +/** + * goo_canvas_set_static_root_item: + * @canvas: a #GooCanvas. + * @item: the static root item. + * + * Sets the static root item. Any existing static items are removed. + * + * Static items are exactly the same as ordinary canvas items, except that + * they do not move or change size when the canvas is scrolled or the scale + * changes. + * + * Static items are added to the static root item in exactly the same way that + * ordinary items are added to the root item. + **/ +void +goo_canvas_set_static_root_item (GooCanvas *canvas, + GooCanvasItem *item) +{ + GooCanvasPrivate *priv; + + g_return_if_fail (GOO_IS_CANVAS (canvas)); + g_return_if_fail (GOO_IS_CANVAS_ITEM (item)); + + priv = GOO_CANVAS_GET_PRIVATE (canvas); + + if (priv->static_root_item == item) + return; + + /* Remove any current model. */ + if (priv->static_root_item_model) + { + g_object_unref (priv->static_root_item_model); + priv->static_root_item_model = NULL; + } + + if (priv->static_root_item) + g_object_unref (priv->static_root_item); + + priv->static_root_item = g_object_ref (item); + goo_canvas_item_set_canvas (priv->static_root_item, canvas); + goo_canvas_item_set_is_static (priv->static_root_item, TRUE); + + canvas->need_update = TRUE; + + if (GTK_WIDGET_REALIZED (canvas)) + goo_canvas_update (canvas); + + gtk_widget_queue_draw (GTK_WIDGET (canvas)); +} + + +/** + * goo_canvas_get_static_root_item_model: + * @canvas: a #GooCanvas. + * + * Gets the static root item model of the canvas. + * + * Static item models are exactly the same as ordinary item models, except that + * the corresponding items do not move or change size when the canvas is + * scrolled or the scale changes. + * + * Static items models are added to the static root item model in exactly the + * same way that ordinary item models are added to the root item model. + * + * Returns: the static root item model, or %NULL. + **/ +GooCanvasItemModel* +goo_canvas_get_static_root_item_model (GooCanvas *canvas) +{ + g_return_val_if_fail (GOO_IS_CANVAS (canvas), NULL); + + return GOO_CANVAS_GET_PRIVATE (canvas)->static_root_item_model; +} + + +/** + * goo_canvas_set_static_root_item_model: + * @canvas: a #GooCanvas. + * @model: the static root item model. + * + * Sets the static root item model. Any existing static item models are + * removed. + * + * Static item models are exactly the same as ordinary item models, except that + * the corresponding items do not move or change size when the canvas is + * scrolled or the scale changes. + * + * Static items models are added to the static root item model in exactly the + * same way that ordinary item models are added to the root item model. + **/ +void +goo_canvas_set_static_root_item_model (GooCanvas *canvas, + GooCanvasItemModel *model) +{ + GooCanvasPrivate *priv; + + g_return_if_fail (GOO_IS_CANVAS (canvas)); + g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (model)); + + priv = GOO_CANVAS_GET_PRIVATE (canvas); + + if (priv->static_root_item_model == model) + return; + + if (priv->static_root_item_model) + { + g_object_unref (priv->static_root_item_model); + priv->static_root_item_model = NULL; + } + + if (priv->static_root_item) + { + g_object_unref (priv->static_root_item); + priv->static_root_item = NULL; + } + + if (model) + { + priv->static_root_item_model = g_object_ref (model); + + /* Create a hierarchy of canvas items for all the items in the model. */ + priv->static_root_item = goo_canvas_create_item (canvas, model); + } + else + { + /* The model has been reset so we go back to a default root group. */ + priv->static_root_item = goo_canvas_group_new (NULL, NULL); + } + + goo_canvas_item_set_canvas (priv->static_root_item, canvas); + goo_canvas_item_set_is_static (priv->static_root_item, TRUE); + canvas->need_update = TRUE; + + if (GTK_WIDGET_REALIZED (canvas)) + goo_canvas_update (canvas); + + gtk_widget_queue_draw (GTK_WIDGET (canvas)); +} + + +/** * goo_canvas_get_item: * @canvas: a #GooCanvas. * @model: a #GooCanvasItemModel. @@ -1014,19 +1239,30 @@ goo_canvas_get_item_at (GooCanvas *canvas, gdouble y, gboolean is_pointer_event) { + GooCanvasPrivate *priv; cairo_t *cr; GooCanvasItem *result = NULL; - GList *list; + GList *list = NULL; g_return_val_if_fail (GOO_IS_CANVAS (canvas), NULL); - /* If no root item is set, just return NULL. */ - if (!canvas->root_item) - return NULL; - + priv = GOO_CANVAS_GET_PRIVATE (canvas); cr = goo_canvas_create_cairo_context (canvas); - list = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr, - is_pointer_event, TRUE, NULL); + + if (canvas->root_item) + list = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr, + is_pointer_event, TRUE, NULL); + + if (!list && priv->static_root_item) + { + gdouble static_x = x, static_y = y; + + goo_canvas_convert_to_static_item_space (canvas, &static_x, &static_y); + list = goo_canvas_item_get_items_at (priv->static_root_item, + static_x, static_y, cr, + is_pointer_event, TRUE, NULL); + } + cairo_destroy (cr); /* We just return the top item in the list. */ @@ -1059,18 +1295,29 @@ goo_canvas_get_items_at (GooCanvas *canvas, gdouble y, gboolean is_pointer_event) { + GooCanvasPrivate *priv; cairo_t *cr; - GList *result; + GList *result = NULL; g_return_val_if_fail (GOO_IS_CANVAS (canvas), NULL); - /* If no root item is set, just return NULL. */ - if (!canvas->root_item) - return NULL; - + priv = GOO_CANVAS_GET_PRIVATE (canvas); cr = goo_canvas_create_cairo_context (canvas); - result = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr, - is_pointer_event, TRUE, NULL); + + if (canvas->root_item) + result = goo_canvas_item_get_items_at (canvas->root_item, x, y, cr, + is_pointer_event, TRUE, NULL); + + if (priv->static_root_item) + { + gdouble static_x = x, static_y = y; + + goo_canvas_convert_to_static_item_space (canvas, &static_x, &static_y); + result = goo_canvas_item_get_items_at (priv->static_root_item, + static_x, static_y, cr, + is_pointer_event, TRUE, result); + } + cairo_destroy (cr); return result; @@ -1181,6 +1428,7 @@ static void goo_canvas_realize (GtkWidget *widget) { GooCanvas *canvas; + GooCanvasPrivate *priv; GdkWindowAttr attributes; gint attributes_mask; gint width_pixels, height_pixels; @@ -1189,6 +1437,7 @@ goo_canvas_realize (GtkWidget *widget) g_return_if_fail (GOO_IS_CANVAS (widget)); canvas = GOO_CANVAS (widget); + priv = GOO_CANVAS_GET_PRIVATE (canvas); GTK_WIDGET_SET_FLAGS (canvas, GTK_REALIZED); attributes.window_type = GDK_WINDOW_CHILD; @@ -1228,6 +1477,9 @@ goo_canvas_realize (GtkWidget *widget) | GDK_FOCUS_CHANGE_MASK | gtk_widget_get_events (widget); + priv->window_x = attributes.x; + priv->window_y = attributes.y; + canvas->canvas_window = gdk_window_new (widget->window, &attributes, attributes_mask); gdk_window_set_user_data (canvas->canvas_window, widget); @@ -1440,6 +1692,74 @@ recalculate_scales (GooCanvas *canvas) } +static void +request_static_redraw (GooCanvas *canvas, + const GooCanvasBounds *bounds) +{ + GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas); + GdkRectangle rect; + + if (!GTK_WIDGET_DRAWABLE (canvas) || (bounds->x1 == bounds->x2)) + return; + + /* We subtract one from the left & top edges, in case anti-aliasing makes + the drawing use an extra pixel. */ + rect.x = (double) bounds->x1 - priv->window_x - 1; + rect.y = (double) bounds->y1 - priv->window_y - 1; + + /* We add an extra one here for the same reason. (The other extra one is to + round up to the next pixel.) And one for luck! */ + rect.width = (double) bounds->x2 - priv->window_x - rect.x + 2 + 1; + rect.height = (double) bounds->y2 - priv->window_y - rect.y + 2 + 1; + + gdk_window_invalidate_rect (canvas->canvas_window, &rect, FALSE); +} + + +/* This requests a redraw of all the toplevel static items at their current + position, but redraws them at their given new position. + We redraw one item at a time to avoid GTK+ merging the rectangles into + one big one. */ +static void +redraw_static_items_at_position (GooCanvas *canvas, + gint x, + gint y) +{ + GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas); + GooCanvasBounds bounds; + GooCanvasItem *item; + gint n_children, i, window_x_copy, window_y_copy; + + if (!priv->static_root_item) + return; + + window_x_copy = priv->window_x; + window_y_copy = priv->window_y; + + n_children = goo_canvas_item_get_n_children (priv->static_root_item); + for (i = 0; i < n_children; i++) + { + item = goo_canvas_item_get_child (priv->static_root_item, i); + + /* Get the bounds of all the static items, relative to the window. */ + goo_canvas_item_get_bounds (item, &bounds); + + /* Request a redraw of the old position. */ + request_static_redraw (canvas, &bounds); + + /* Redraw the item in its new position. */ + priv->window_x = x; + priv->window_y = y; + + gdk_window_process_updates (canvas->canvas_window, TRUE); + + /* Now reset the window position. */ + priv->window_x = window_x_copy; + priv->window_y = window_y_copy; + } +} + + /* This makes sure the canvas is all set up correctly, i.e. the scrollbar adjustments are set, the canvas x & y offsets are calculated, and the canvas window is sized. */ @@ -1648,18 +1968,52 @@ static void goo_canvas_adjustment_value_changed (GtkAdjustment *adjustment, GooCanvas *canvas) { + GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas); AtkObject *accessible; if (!canvas->freeze_count && GTK_WIDGET_REALIZED (canvas)) { + if (canvas->redraw_when_scrolled) + { + /* Map the temporary window to stop the canvas window being scrolled. + When it is unmapped the entire canvas will be redrawn. */ + if (GTK_WIDGET_MAPPED (canvas)) + gdk_window_show (canvas->tmp_window); + } + else + { + /* Redraw the area currently occupied by the static items. But + draw the static items in their new position. This stops them + from being "dragged" when the window is scrolled. */ + redraw_static_items_at_position (canvas, + -canvas->hadjustment->value, + -canvas->hadjustment->value); + + /* Move the static items to the new position. */ + priv->window_x = -canvas->hadjustment->value; + priv->window_y = -canvas->vadjustment->value; + } + gdk_window_move (canvas->canvas_window, - canvas->hadjustment->value, - canvas->vadjustment->value); - - /* If this is callback from a signal for one of the scrollbars, process - updates here for smoother scrolling. */ - if (adjustment) - gdk_window_process_updates (canvas->canvas_window, TRUE); + + if (canvas->redraw_when_scrolled) + { + /* Unmap the temporary window, causing the entire canvas to be + redrawn. */ + if (GTK_WIDGET_MAPPED (canvas)) + gdk_window_hide (canvas->tmp_window); + } + else + { + /* Process updates here for smoother scrolling. */ + gdk_window_process_updates (canvas->canvas_window, TRUE); + + /* Now ensure the static items are redrawn in their new position. */ + redraw_static_items_at_position (canvas, priv->window_x, + priv->window_y); + } /* Notify any accessibility modules that the view has changed. */ accessible = gtk_widget_get_accessible (GTK_WIDGET (canvas)); @@ -1865,6 +2219,10 @@ goo_canvas_scroll_to_item (GooCanvas *canvas, GooCanvasBounds bounds; gdouble hvalue, vvalue; + /* We can't scroll to static items. */ + if (goo_canvas_item_get_is_static (item)) + return; + goo_canvas_item_get_bounds (item, &bounds); goo_canvas_convert_to_pixels (canvas, &bounds.x1, &bounds.y1); @@ -2095,7 +2453,8 @@ static void goo_canvas_update_internal (GooCanvas *canvas, cairo_t *cr) { - GooCanvasBounds bounds; + GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas); + GooCanvasBounds bounds, static_bounds; /* It is possible that processing the first set of updates causes other updates to be scheduled, so we loop round until all are done. Items @@ -2108,6 +2467,10 @@ goo_canvas_update_internal (GooCanvas *canvas, canvas->need_entire_subtree_update = FALSE; if (canvas->root_item) goo_canvas_item_update (canvas->root_item, entire_tree, cr, &bounds); + + if (priv->static_root_item) + goo_canvas_item_update (priv->static_root_item, entire_tree, cr, + &static_bounds); } /* If the bounds are automatically-calculated, update them now. */ @@ -2189,12 +2552,13 @@ goo_canvas_request_update (GooCanvas *canvas) /** * goo_canvas_request_redraw: * @canvas: a #GooCanvas. - * @bounds: the bounds to redraw. + * @bounds: the bounds to redraw, in device space. * * This function is only intended to be used by subclasses of #GooCanvas or * #GooCanvasItem implementations. * - * Requests that the given bounds be redrawn. + * Requests that the given bounds be redrawn. The bounds must be in the canvas + * coordinate space. **/ void goo_canvas_request_redraw (GooCanvas *canvas, @@ -2224,6 +2588,58 @@ goo_canvas_request_redraw (GooCanvas *canvas, } +/** + * goo_canvas_request_item_redraw: + * @canvas: a #GooCanvas. + * @bounds: the bounds of the item to redraw. + * @is_static: if the item is static. + * + * This function is only intended to be used by subclasses of #GooCanvas or + * #GooCanvasItem implementations. + * + * Requests that the given bounds be redrawn. If @is_static is %TRUE the bounds + * are assumed to be in the static item coordinate space, otherwise they are + * assumed to be in the canvas coordinate space. + * + * If @is_static is %FALSE this function behaves the same as + * goo_canvas_request_redraw(). + **/ +void +goo_canvas_request_item_redraw (GooCanvas *canvas, + const GooCanvasBounds *bounds, + gboolean is_static) +{ + if (is_static) + request_static_redraw (canvas, bounds); + else + goo_canvas_request_redraw (canvas, bounds); +} + + +static void +paint_static_items (GooCanvas *canvas, + GdkEventExpose *event, + cairo_t *cr) +{ + GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas); + GooCanvasBounds static_bounds; + double static_x_offset, static_y_offset; + + cairo_save (cr); + cairo_identity_matrix (cr); + static_x_offset = floor (canvas->hadjustment->value); + static_y_offset = floor (canvas->vadjustment->value); + cairo_translate (cr, static_x_offset, static_y_offset); + /* FIXME: Uses pixels at present - use canvas units instead? */ + static_bounds.x1 = event->area.x - static_x_offset; + static_bounds.y1 = event->area.y - static_y_offset; + static_bounds.x2 = event->area.width + static_bounds.x1; + static_bounds.y2 = event->area.height + static_bounds.y1; + goo_canvas_item_paint (priv->static_root_item, cr, &static_bounds, 1.0); + cairo_restore (cr); +} + + static gboolean goo_canvas_expose_event (GtkWidget *widget, GdkEventExpose *event) @@ -2231,6 +2647,7 @@ goo_canvas_expose_event (GtkWidget *widget, GooCanvas *canvas = GOO_CANVAS (widget); GooCanvasBounds bounds, root_item_bounds; cairo_t *cr; + double x1, y1, x2, y2; if (!canvas->root_item) return FALSE; @@ -2282,17 +2699,26 @@ goo_canvas_expose_event (GtkWidget *widget, || (root_item_bounds.y2 > canvas->bounds.y2 && canvas->bounds.y2 < bounds.y2)) { + /* Clip to the intersection of the canvas bounds and the expose + bounds, to avoid cairo's 16-bit limits. */ + x1 = MAX (canvas->bounds.x1, bounds.x1); + y1 = MAX (canvas->bounds.y1, bounds.y1); + x2 = MIN (canvas->bounds.x2, bounds.x2); + y2 = MIN (canvas->bounds.y2, bounds.y2); + cairo_new_path (cr); - cairo_move_to (cr, canvas->bounds.x1, canvas->bounds.y1); - cairo_line_to (cr, canvas->bounds.x2, canvas->bounds.y1); - cairo_line_to (cr, canvas->bounds.x2, canvas->bounds.y2); - cairo_line_to (cr, canvas->bounds.x1, canvas->bounds.y2); + cairo_move_to (cr, x1, y1); + cairo_line_to (cr, x2, y1); + cairo_line_to (cr, x2, y2); + cairo_line_to (cr, x1, y2); cairo_close_path (cr); cairo_clip (cr); } goo_canvas_item_paint (canvas->root_item, cr, &bounds, canvas->scale); + paint_static_items (canvas, event, cr); + cairo_destroy (cr); GTK_WIDGET_CLASS (goo_canvas_parent_class)->expose_event (widget, event); @@ -2386,6 +2812,15 @@ initialize_crossing_event (GooCanvas *canvas, crossing_event->state = event->crossing.state; break; + case GDK_SCROLL: + crossing_event->time = event->scroll.time; + crossing_event->x = event->scroll.x; + crossing_event->y = event->scroll.y; + crossing_event->x_root = event->scroll.x_root; + crossing_event->y_root = event->scroll.y_root; + crossing_event->state = event->scroll.state; + break; + default: /* It must be a button press/release event. */ crossing_event->time = event->button.time; @@ -2501,6 +2936,12 @@ emit_pointer_event (GooCanvas *canvas, x_root = &event.crossing.x_root; y_root = &event.crossing.y_root; break; + case GDK_SCROLL: + x = &event.scroll.x; + y = &event.scroll.y; + x_root = &event.scroll.x_root; + y_root = &event.scroll.y_root; + break; default: /* It must be a button press/release event. */ x = &event.button.x; @@ -2517,6 +2958,10 @@ emit_pointer_event (GooCanvas *canvas, /* Convert to the canvas coordinate space. */ goo_canvas_convert_from_pixels (canvas, x, y); + /* Convert to static item space, if necessary. */ + if (target_item && goo_canvas_item_get_is_static (target_item)) + goo_canvas_convert_to_static_item_space (canvas, x, y); + /* Copy to the x_root & y_root fields. */ *x_root = *x; *y_root = *y; @@ -2708,6 +3153,14 @@ goo_canvas_scroll (GtkWidget *widget, GtkAdjustment *adj; gdouble delta, new_value; + if (event->window == canvas->canvas_window) + { + /* See if the current item wants the scroll event. */ + update_pointer_item (canvas, (GdkEvent*) event); + if (emit_pointer_event (canvas, "scroll_event", (GdkEvent*) event)) + return TRUE; + } + if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_DOWN) adj = canvas->vadjustment; else @@ -3132,22 +3585,23 @@ goo_canvas_convert_from_window_pixels (GooCanvas *canvas, } -/** - * goo_canvas_convert_to_item_space: - * @canvas: a #GooCanvas. - * @item: a #GooCanvasItem. - * @x: a pointer to the x coordinate to convert. - * @y: a pointer to the y coordinate to convert. - * - * Converts a coordinate from the canvas coordinate space to the given - * item's coordinate space, applying all transformation matrices including the - * item's own transformation matrix, if it has one. - **/ -void -goo_canvas_convert_to_item_space (GooCanvas *canvas, - GooCanvasItem *item, - gdouble *x, - gdouble *y) +/* Converts from the canvas coordinate space to the static item coordinate + space, i.e. in pixels from the top-left of the viewport window. */ +static void +goo_canvas_convert_to_static_item_space (GooCanvas *canvas, + gdouble *x, + gdouble *y) +{ + *x = ((*x - canvas->bounds.x1) * canvas->device_to_pixels_x) + + canvas->canvas_x_offset - canvas->hadjustment->value; + *y = ((*y - canvas->bounds.y1) * canvas->device_to_pixels_y) + + canvas->canvas_y_offset - canvas->vadjustment->value; +} + + +static void +get_transform_to_item_space (GooCanvasItem *item, + cairo_matrix_t *transform) { GooCanvasItem *tmp = item, *parent, *child; GList *list = NULL, *l; @@ -3176,8 +3630,31 @@ goo_canvas_convert_to_item_space (GooCanvas *canvas, } g_list_free (list); - /* Now convert the coordinates. */ - cairo_matrix_transform_point (&inverse, x, y); + *transform = inverse; +} + + +/** + * goo_canvas_convert_to_item_space: + * @canvas: a #GooCanvas. + * @item: a #GooCanvasItem. + * @x: a pointer to the x coordinate to convert. + * @y: a pointer to the y coordinate to convert. + * + * Converts a coordinate from the canvas coordinate space to the given + * item's coordinate space, applying all transformation matrices including the + * item's own transformation matrix, if it has one. + **/ +void +goo_canvas_convert_to_item_space (GooCanvas *canvas, + GooCanvasItem *item, + gdouble *x, + gdouble *y) +{ + cairo_matrix_t transform; + + get_transform_to_item_space (item, &transform); + cairo_matrix_transform_point (&transform, x, y); } @@ -3219,7 +3696,7 @@ goo_canvas_convert_from_item_space (GooCanvas *canvas, &item_transform); if (has_transform) { - cairo_matrix_multiply (&transform, &transform, &item_transform); + cairo_matrix_multiply (&transform, &item_transform, &transform); } } g_list_free (list); @@ -3229,6 +3706,56 @@ goo_canvas_convert_from_item_space (GooCanvas *canvas, } +/** + * goo_canvas_convert_bounds_to_item_space: + * @canvas: a #GooCanvas. + * @item: a #GooCanvasItem. + * @bounds: the bounds in canvas coordinate space, to be converted. + * + * Converts the given bounds in the canvas coordinate space to a bounding box + * in item space. This is useful in the item paint() methods to convert the + * bounds to be painted to the item's coordinate space. + **/ +void +goo_canvas_convert_bounds_to_item_space (GooCanvas *canvas, + GooCanvasItem *item, + GooCanvasBounds *bounds) +{ + GooCanvasBounds tmp_bounds = *bounds, tmp_bounds2 = *bounds; + cairo_matrix_t transform; + + get_transform_to_item_space (item, &transform); + + /* Convert the top-left and bottom-right corners to device coords. */ + cairo_matrix_transform_point (&transform, &tmp_bounds.x1, &tmp_bounds.y1); + cairo_matrix_transform_point (&transform, &tmp_bounds.x2, &tmp_bounds.y2); + + /* Now convert the top-right and bottom-left corners. */ + cairo_matrix_transform_point (&transform, &tmp_bounds2.x1, &tmp_bounds2.y2); + cairo_matrix_transform_point (&transform, &tmp_bounds2.x2, &tmp_bounds2.y1); + + /* Calculate the minimum x coordinate seen and put in x1. */ + bounds->x1 = MIN (tmp_bounds.x1, tmp_bounds.x2); + bounds->x1 = MIN (bounds->x1, tmp_bounds2.x1); + bounds->x1 = MIN (bounds->x1, tmp_bounds2.x2); + + /* Calculate the maximum x coordinate seen and put in x2. */ + bounds->x2 = MAX (tmp_bounds.x1, tmp_bounds.x2); + bounds->x2 = MAX (bounds->x2, tmp_bounds2.x1); + bounds->x2 = MAX (bounds->x2, tmp_bounds2.x2); + + /* Calculate the minimum y coordinate seen and put in y1. */ + bounds->y1 = MIN (tmp_bounds.y1, tmp_bounds.y2); + bounds->y1 = MIN (bounds->y1, tmp_bounds2.y1); + bounds->y1 = MIN (bounds->y1, tmp_bounds2.y2); + + /* Calculate the maximum y coordinate seen and put in y2. */ + bounds->y2 = MAX (tmp_bounds.y1, tmp_bounds.y2); + bounds->y2 = MAX (bounds->y2, tmp_bounds2.y1); + bounds->y2 = MAX (bounds->y2, tmp_bounds2.y2); +} + + /* * Keyboard focus navigation. */ @@ -3796,3 +4323,49 @@ goo_canvas_remove (GtkContainer *container, } } } + + +static gboolean +goo_canvas_query_tooltip (GtkWidget *widget, + gint x, + gint y, + gboolean keyboard_tip, + GtkTooltip *tooltip) +{ + GooCanvas *canvas = (GooCanvas*) widget; + GooCanvasItem *item = canvas->pointer_item, *parent; + gdouble item_x = x, item_y = y; + gboolean tip_set = FALSE, has_transform; + cairo_matrix_t transform; + + if (!item) + return FALSE; + + /* Convert from pixels to the item's coordinate space. */ + goo_canvas_convert_from_pixels (canvas, &item_x, &item_y); + goo_canvas_convert_to_item_space (canvas, item, &item_x, &item_y); + + for (;;) + { + g_signal_emit_by_name (item, "query-tooltip", item_x, item_y, + keyboard_tip, tooltip, &tip_set); + if (tip_set) + return TRUE; + + parent = goo_canvas_item_get_parent (item); + if (!parent) + break; + + /* Convert x & y to the parent's coordinate space. */ + has_transform = goo_canvas_item_get_transform_for_child (parent, item, + &transform); + if (has_transform) + cairo_matrix_transform_point (&transform, &item_x, &item_y); + + item = parent; + } + + /* We call the parent method in case the canvas itself has a tooltip set. */ + return GTK_WIDGET_CLASS (goo_canvas_parent_class)->query_tooltip (widget, x, y, keyboard_tip, tooltip); +} + diff --git a/src/goocanvas/src/goocanvas.h b/src/goocanvas/src/goocanvas.h index 56e38ff..c68b0c2 100644 --- a/src/goocanvas/src/goocanvas.h +++ b/src/goocanvas/src/goocanvas.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,10 @@ struct _GooCanvas /* This is TRUE if the background is cleared before painting the canvas. */ guint clear_background : 1; + /* This is TRUE if the canvas is completely redrawn when scrolled. It is + useful when there are sticky items to reduce flicker, but is slower. */ + guint redraw_when_scrolled : 1; + /* This is the padding around the automatic bounds. */ gdouble bounds_padding; @@ -204,6 +209,14 @@ GooCanvasItemModel* goo_canvas_get_root_item_model (GooCanvas *canvas); void goo_canvas_set_root_item_model (GooCanvas *canvas, GooCanvasItemModel *model); +GooCanvasItem* goo_canvas_get_static_root_item (GooCanvas *canvas); +void goo_canvas_set_static_root_item (GooCanvas *canvas, + GooCanvasItem *item); + +GooCanvasItemModel* goo_canvas_get_static_root_item_model (GooCanvas *canvas); +void goo_canvas_set_static_root_item_model (GooCanvas *canvas, + GooCanvasItemModel *model); + GooCanvasItem* goo_canvas_get_item (GooCanvas *canvas, GooCanvasItemModel *model); GooCanvasItem* goo_canvas_get_item_at (GooCanvas *canvas, @@ -265,6 +278,9 @@ void goo_canvas_convert_from_item_space (GooCanvas *canvas, GooCanvasItem *item, gdouble *x, gdouble *y); +void goo_canvas_convert_bounds_to_item_space (GooCanvas *canvas, + GooCanvasItem *item, + GooCanvasBounds *bounds); /* @@ -299,6 +315,9 @@ void goo_canvas_update (GooCanvas *canvas); void goo_canvas_request_update (GooCanvas *canvas); void goo_canvas_request_redraw (GooCanvas *canvas, const GooCanvasBounds *bounds); +void goo_canvas_request_item_redraw (GooCanvas *canvas, + const GooCanvasBounds *bounds, + gboolean is_static); gdouble goo_canvas_get_default_line_width (GooCanvas *canvas); diff --git a/src/goocanvas/src/goocanvasatk.c b/src/goocanvas/src/goocanvasatk.c index f32bb64..5c8c774 100644 --- a/src/goocanvas/src/goocanvasatk.c +++ b/src/goocanvas/src/goocanvasatk.c @@ -20,6 +20,7 @@ typedef AtkGObjectAccessible GooCanvasItemAccessible; typedef AtkGObjectAccessibleClass GooCanvasItemAccessibleClass; +#define GOO_TYPE_CANVAS_ITEM_ACCESSIBLE (goo_canvas_item_accessible_get_type ()) #define GOO_IS_CANVAS_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), goo_canvas_item_accessible_get_type ())) static void goo_canvas_item_accessible_component_interface_init (AtkComponentIface *iface); @@ -50,15 +51,19 @@ goo_canvas_item_accessible_get_item_extents (GooCanvasItem *item, /* Get the bounds in device units. */ goo_canvas_item_get_bounds (item, &bounds); - /* Convert to pixels within the entire canvas. */ - goo_canvas_convert_to_pixels (canvas, &bounds.x1, &bounds.y1); - goo_canvas_convert_to_pixels (canvas, &bounds.x2, &bounds.y2); - - /* Convert to pixels within the visible window. */ - bounds.x1 -= canvas->hadjustment->value; - bounds.y1 -= canvas->vadjustment->value; - bounds.x2 -= canvas->hadjustment->value; - bounds.y2 -= canvas->vadjustment->value; + /* Static items are in pixels so don't need converting. */ + if (!goo_canvas_item_get_is_static (item)) + { + /* Convert to pixels within the entire canvas. */ + goo_canvas_convert_to_pixels (canvas, &bounds.x1, &bounds.y1); + goo_canvas_convert_to_pixels (canvas, &bounds.x2, &bounds.y2); + + /* Convert to pixels within the visible window. */ + bounds.x1 -= canvas->hadjustment->value; + bounds.y1 -= canvas->vadjustment->value; + bounds.x2 -= canvas->hadjustment->value; + bounds.y2 -= canvas->vadjustment->value; + } /* Round up or down to integers. */ rect->x = floor (bounds.x1); @@ -491,7 +496,7 @@ typedef AtkGObjectAccessibleClass GooCanvasWidgetAccessibleClass; #define GOO_IS_CANVAS_WIDGET_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), goo_canvas_widget_accessible_get_type ())) G_DEFINE_TYPE (GooCanvasWidgetAccessible, goo_canvas_widget_accessible, - GOO_TYPE_CANVAS_ITEM) + GOO_TYPE_CANVAS_ITEM_ACCESSIBLE) static void @@ -570,7 +575,7 @@ goo_canvas_widget_accessible_init (GooCanvasWidgetAccessible *accessible) } -AtkObject* +static AtkObject* goo_canvas_widget_accessible_new (GObject *object) { AtkObject *accessible; diff --git a/src/goocanvas/src/goocanvasellipse.c b/src/goocanvas/src/goocanvasellipse.c index 7453a4c..6653f50 100644 --- a/src/goocanvas/src/goocanvasellipse.c +++ b/src/goocanvas/src/goocanvasellipse.c @@ -23,6 +23,10 @@ * * To get or set the properties of an existing #GooCanvasEllipse, use * g_object_get() and g_object_set(). + * + * The ellipse can be specified either with the "center-x", "center-y", + * "radius-x" and "radius-y" properties, or with the "x", "y", "width" and + * "height" properties. */ #include #include @@ -37,7 +41,12 @@ enum { PROP_CENTER_X, PROP_CENTER_Y, PROP_RADIUS_X, - PROP_RADIUS_Y + PROP_RADIUS_Y, + + PROP_X, + PROP_Y, + PROP_WIDTH, + PROP_HEIGHT }; @@ -92,6 +101,36 @@ goo_canvas_ellipse_install_common_properties (GObjectClass *gobject_class) _("The vertical radius of the ellipse"), 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_X, + g_param_spec_double ("x", + "X", + _("The x coordinate of the left side of the ellipse"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_Y, + g_param_spec_double ("y", + "Y", + _("The y coordinate of the top of the ellipse"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_WIDTH, + g_param_spec_double ("width", + _("Width"), + _("The width of the ellipse"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_HEIGHT, + g_param_spec_double ("height", + _("Height"), + _("The height of the ellipse"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); } @@ -224,6 +263,18 @@ goo_canvas_ellipse_get_common_property (GObject *object, case PROP_RADIUS_Y: g_value_set_double (value, ellipse_data->radius_y); break; + case PROP_X: + g_value_set_double (value, ellipse_data->center_x - ellipse_data->radius_x); + break; + case PROP_Y: + g_value_set_double (value, ellipse_data->center_y - ellipse_data->radius_y); + break; + case PROP_WIDTH: + g_value_set_double (value, 2.0 * ellipse_data->radius_x); + break; + case PROP_HEIGHT: + g_value_set_double (value, 2.0 * ellipse_data->radius_y); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -251,19 +302,55 @@ goo_canvas_ellipse_set_common_property (GObject *object, const GValue *value, GParamSpec *pspec) { + gdouble x, y; + switch (prop_id) { case PROP_CENTER_X: ellipse_data->center_x = g_value_get_double (value); + g_object_notify (object, "x"); break; case PROP_CENTER_Y: ellipse_data->center_y = g_value_get_double (value); + g_object_notify (object, "y"); break; case PROP_RADIUS_X: ellipse_data->radius_x = g_value_get_double (value); + g_object_notify (object, "width"); break; case PROP_RADIUS_Y: ellipse_data->radius_y = g_value_get_double (value); + g_object_notify (object, "height"); + break; + case PROP_X: + ellipse_data->center_x = g_value_get_double (value) + ellipse_data->radius_x; + g_object_notify (object, "center-x"); + break; + case PROP_Y: + ellipse_data->center_y = g_value_get_double (value) + ellipse_data->radius_y; + g_object_notify (object, "center-y"); + break; + case PROP_WIDTH: + /* Calculate the current x coordinate. */ + x = ellipse_data->center_x - ellipse_data->radius_x; + /* Calculate the new radius_x, which is half the width. */ + ellipse_data->radius_x = g_value_get_double (value) / 2.0; + /* Now calculate the new center_x. */ + ellipse_data->center_x = x + ellipse_data->radius_x; + + g_object_notify (object, "center-x"); + g_object_notify (object, "radius-x"); + break; + case PROP_HEIGHT: + /* Calculate the current y coordinate. */ + y = ellipse_data->center_y - ellipse_data->radius_y; + /* Calculate the new radius_y, which is half the height. */ + ellipse_data->radius_y = g_value_get_double (value) / 2.0; + /* Now calculate the new center_y. */ + ellipse_data->center_y = y + ellipse_data->radius_y; + + g_object_notify (object, "center-y"); + g_object_notify (object, "radius-y"); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -356,6 +443,10 @@ canvas_item_interface_init (GooCanvasItemIface *iface) * To get or set the properties of an existing #GooCanvasEllipseModel, use * g_object_get() and g_object_set(). * + * The ellipse can be specified either with the "center-x", "center-y", + * "radius-x" and "radius-y" properties, or with the "x", "y", "width" and + * "height" properties. + * * To respond to events such as mouse clicks on the ellipse you must connect * to the signal handlers of the corresponding #GooCanvasEllipse objects. * (See goo_canvas_get_item() and #GooCanvas::item-created.) diff --git a/src/goocanvas/src/goocanvasgrid.c b/src/goocanvas/src/goocanvasgrid.c new file mode 100644 index 0000000..80190dd --- /dev/null +++ b/src/goocanvas/src/goocanvasgrid.c @@ -0,0 +1,1170 @@ +/* + * GooCanvas. Copyright (C) 2005-8 Damon Chaplin. + * Released under the GNU LGPL license. See COPYING for details. + * + * goocanvasgrid.c - a grid item. + */ + +/** + * SECTION:goocanvasgrid + * @Title: GooCanvasGrid + * @Short_Description: a grid item. + * + * GooCanvasGrid represents a grid item. + * A grid consists of a number of equally-spaced horizontal and vertical + * grid lines, plus an optional border. + * + * It is a subclass of #GooCanvasItemSimple and so inherits all of the style + * properties such as "stroke-color", "fill-color" and "line-width". + * + * It also implements the #GooCanvasItem interface, so you can use the + * #GooCanvasItem functions such as goo_canvas_item_raise() and + * goo_canvas_item_rotate(). + * + * To create a #GooCanvasGrid use goo_canvas_grid_new(). + * + * To get or set the properties of an existing #GooCanvasGrid, use + * g_object_get() and g_object_set(). + * + * The grid's position and size is specified with the #GooCanvasGrid:x, + * #GooCanvasGrid:y, #GooCanvasGrid:width and #GooCanvasGrid:height properties. + * + * The #GooCanvasGrid:x-step and #GooCanvasGrid:y-step properties specify the + * distance between grid lines. The #GooCanvasGrid:x-offset and + * #GooCanvasGrid:y-offset properties specify the distance before the first + * grid lines. + * + * The horizontal or vertical grid lines can be hidden using the + * #GooCanvasGrid:show-horz-grid-lines and #GooCanvasGrid:show-vert-grid-lines + * properties. + * + * The width of the border can be set using the #GooCanvasGrid:border-width + * property. The border is drawn outside the area specified with the + * #GooCanvasGrid:x, #GooCanvasGrid:y, #GooCanvasGrid:width and + * #GooCanvasGrid:height properties. + * + * Other properties allow the colors and widths of the grid lines to be set. + * The grid line color and width properties override the standard + * #GooCanvasItemSimple:stroke-color and #GooCanvasItemSimple:line-width + * properties, enabling different styles for horizontal and vertical grid lines. + */ +#include +#include +#include +#include +#include "goocanvasprivate.h" +#include "goocanvas.h" + + +enum { + PROP_0, + + PROP_X, + PROP_Y, + PROP_WIDTH, + PROP_HEIGHT, + PROP_X_STEP, + PROP_Y_STEP, + PROP_X_OFFSET, + PROP_Y_OFFSET, + PROP_HORZ_GRID_LINE_WIDTH, + PROP_VERT_GRID_LINE_WIDTH, + PROP_HORZ_GRID_LINE_PATTERN, + PROP_VERT_GRID_LINE_PATTERN, + PROP_BORDER_WIDTH, + PROP_BORDER_PATTERN, + PROP_SHOW_HORZ_GRID_LINES, + PROP_SHOW_VERT_GRID_LINES, + PROP_VERT_GRID_LINES_ON_TOP, + + /* Convenience properties. */ + PROP_HORZ_GRID_LINE_COLOR, + PROP_HORZ_GRID_LINE_COLOR_RGBA, + PROP_HORZ_GRID_LINE_PIXBUF, + PROP_VERT_GRID_LINE_COLOR, + PROP_VERT_GRID_LINE_COLOR_RGBA, + PROP_VERT_GRID_LINE_PIXBUF, + PROP_BORDER_COLOR, + PROP_BORDER_COLOR_RGBA, + PROP_BORDER_PIXBUF +}; + + +GooCanvasItemIface *goo_canvas_grid_parent_iface; + +static void canvas_item_interface_init (GooCanvasItemIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GooCanvasGrid, goo_canvas_grid, + GOO_TYPE_CANVAS_ITEM_SIMPLE, + G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM, + canvas_item_interface_init)) + + +static void +goo_canvas_grid_install_common_properties (GObjectClass *gobject_class) +{ + g_object_class_install_property (gobject_class, PROP_X, + g_param_spec_double ("x", + "X", + _("The x coordinate of the grid"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_Y, + g_param_spec_double ("y", + "Y", + _("The y coordinate of the grid"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_WIDTH, + g_param_spec_double ("width", + _("Width"), + _("The width of the grid"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_HEIGHT, + g_param_spec_double ("height", + _("Height"), + _("The height of the grid"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_X_STEP, + g_param_spec_double ("x-step", + "X Step", + _("The distance between the vertical grid lines"), + 0.0, G_MAXDOUBLE, 10.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_Y_STEP, + g_param_spec_double ("y-step", + "Y Step", + _("The distance between the horizontal grid lines"), + 0.0, G_MAXDOUBLE, 10.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_X_OFFSET, + g_param_spec_double ("x-offset", + "X Offset", + _("The distance before the first vertical grid line"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_Y_OFFSET, + g_param_spec_double ("y-offset", + "Y Offset", + _("The distance before the first horizontal grid line"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_WIDTH, + g_param_spec_double ("horz-grid-line-width", + _("Horizontal Grid Line Width"), + _("The width of the horizontal grid lines"), + -G_MAXDOUBLE, + G_MAXDOUBLE, -1.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_WIDTH, + g_param_spec_double ("vert-grid-line-width", + _("Vertical Grid Line Width"), + _("The width of the vertical grid lines"), + -G_MAXDOUBLE, + G_MAXDOUBLE, -1.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_PATTERN, + g_param_spec_boxed ("horz-grid-line-pattern", + _("Horizontal Grid Line Pattern"), + _("The cairo pattern to paint the horizontal grid lines with"), + GOO_TYPE_CAIRO_PATTERN, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_PATTERN, + g_param_spec_boxed ("vert-grid-line-pattern", + _("Vertical Grid Line Pattern"), + _("The cairo pattern to paint the vertical grid lines with"), + GOO_TYPE_CAIRO_PATTERN, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_BORDER_WIDTH, + g_param_spec_double ("border-width", + _("Border Width"), + _("The width of the border around the grid"), + -G_MAXDOUBLE, + G_MAXDOUBLE, -1.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_BORDER_PATTERN, + g_param_spec_boxed ("border-pattern", + _("Border Pattern"), + _("The cairo pattern to paint the border with"), + GOO_TYPE_CAIRO_PATTERN, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_SHOW_HORZ_GRID_LINES, + g_param_spec_boolean ("show-horz-grid-lines", + _("Show Horizontal Grid Lines"), + _("If the horizontal grid lines are shown"), + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_SHOW_VERT_GRID_LINES, + g_param_spec_boolean ("show-vert-grid-lines", + _("Show Vertical Grid Lines"), + _("If the vertical grid lines are shown"), + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINES_ON_TOP, + g_param_spec_boolean ("vert-grid-lines-on-top", + _("Vertical Grid Lines On Top"), + _("If the vertical grid lines are painted above the horizontal grid lines"), + FALSE, + G_PARAM_READWRITE)); + + + /* Convenience properties - some are writable only. */ + g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_COLOR, + g_param_spec_string ("horz-grid-line-color", + _("Horizontal Grid Line Color"), + _("The color to use for the horizontal grid lines"), + NULL, + G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_COLOR_RGBA, + g_param_spec_uint ("horz-grid-line-color-rgba", + _("Horizontal Grid Line Color RGBA"), + _("The color to use for the horizontal grid lines, specified as a 32-bit integer value"), + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_PIXBUF, + g_param_spec_object ("horz-grid-line-pixbuf", + _("Horizontal Grid Line Pixbuf"), + _("The pixbuf to use to draw the horizontal grid lines"), + GDK_TYPE_PIXBUF, + G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_COLOR, + g_param_spec_string ("vert-grid-line-color", + _("Vertical Grid Line Color"), + _("The color to use for the vertical grid lines"), + NULL, + G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_COLOR_RGBA, + g_param_spec_uint ("vert-grid-line-color-rgba", + _("Vertical Grid Line Color RGBA"), + _("The color to use for the vertical grid lines, specified as a 32-bit integer value"), + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_PIXBUF, + g_param_spec_object ("vert-grid-line-pixbuf", + _("Vertical Grid Line Pixbuf"), + _("The pixbuf to use to draw the vertical grid lines"), + GDK_TYPE_PIXBUF, + G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_BORDER_COLOR, + g_param_spec_string ("border-color", + _("Border Color"), + _("The color to use for the border"), + NULL, + G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_BORDER_COLOR_RGBA, + g_param_spec_uint ("border-color-rgba", + _("Border Color RGBA"), + _("The color to use for the border, specified as a 32-bit integer value"), + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_BORDER_PIXBUF, + g_param_spec_object ("border-pixbuf", + _("Border Pixbuf"), + _("The pixbuf to use to draw the border"), + GDK_TYPE_PIXBUF, + G_PARAM_WRITABLE)); +} + + +/* This initializes the common grid data. */ +static void +goo_canvas_grid_init_data (GooCanvasGridData *grid_data) +{ + grid_data->x = 0.0; + grid_data->y = 0.0; + grid_data->width = 0.0; + grid_data->height = 0.0; + grid_data->x_step = 10.0; + grid_data->y_step = 10.0; + grid_data->x_offset = 0.0; + grid_data->y_offset = 0.0; + grid_data->horz_grid_line_width = -1.0; + grid_data->vert_grid_line_width = -1.0; + grid_data->horz_grid_line_pattern = NULL; + grid_data->vert_grid_line_pattern = NULL; + grid_data->border_width = -1.0; + grid_data->border_pattern = NULL; + grid_data->show_horz_grid_lines = TRUE; + grid_data->show_vert_grid_lines = TRUE; + grid_data->vert_grid_lines_on_top = FALSE; +} + + +/* This frees the contents of the grid data, but not the struct itself. */ +static void +goo_canvas_grid_free_data (GooCanvasGridData *grid_data) +{ + +} + + +static void +goo_canvas_grid_init (GooCanvasGrid *grid) +{ + grid->grid_data = g_slice_new0 (GooCanvasGridData); + goo_canvas_grid_init_data (grid->grid_data); +} + + +/** + * goo_canvas_grid_new: + * @parent: the parent item, or %NULL. If a parent is specified, it will assume + * ownership of the item, and the item will automatically be freed when it is + * removed from the parent. Otherwise call g_object_unref() to free it. + * @x: the x coordinate of the left of the grid. + * @y: the y coordinate of the top of the grid. + * @width: the width of the grid. + * @height: the height of the grid. + * @x_step: the distance between the vertical grid lines. + * @y_step: the distance between the horizontal grid lines. + * @x_offset: the distance before the first vertical grid line. + * @y_offset: the distance before the first horizontal grid line. + * @...: optional pairs of property names and values, and a terminating %NULL. + * + * Creates a new grid item. + * + * + * + * Here's an example showing how to create a grid: + * + * + * GooCanvasItem *grid = goo_canvas_grid_new (mygroup, 100.0, 100.0, 400.0, 200.0, + * 20.0, 20.0, 10.0, 10.0, + * "horz-grid-line-width", 4.0, + * "horz-grid-line-color", "yellow", + * "vert-grid-line-width", 2.0, + * "vert-grid-line-color", "red", + * "border-width", 3.0, + * "border-color", "white", + * "fill-color", "blue", + * NULL); + * + * + * Returns: a new grid item. + **/ +GooCanvasItem* +goo_canvas_grid_new (GooCanvasItem *parent, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + gdouble x_step, + gdouble y_step, + gdouble x_offset, + gdouble y_offset, + ...) +{ + GooCanvasItem *item; + GooCanvasGrid *grid; + GooCanvasGridData *grid_data; + va_list var_args; + const char *first_property; + + item = g_object_new (GOO_TYPE_CANVAS_GRID, NULL); + grid = (GooCanvasGrid*) item; + + grid_data = grid->grid_data; + grid_data->x = x; + grid_data->y = y; + grid_data->width = width; + grid_data->height = height; + grid_data->x_step = x_step; + grid_data->y_step = y_step; + grid_data->x_offset = x_offset; + grid_data->y_offset = y_offset; + + va_start (var_args, y_offset); + first_property = va_arg (var_args, char*); + if (first_property) + g_object_set_valist (G_OBJECT (item), first_property, var_args); + va_end (var_args); + + if (parent) + { + goo_canvas_item_add_child (parent, item, -1); + g_object_unref (item); + } + + return item; +} + + +static void +goo_canvas_grid_finalize (GObject *object) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object; + GooCanvasGrid *grid = (GooCanvasGrid*) object; + + /* Free our data if we didn't have a model. (If we had a model it would + have been reset in dispose() and simple_data will be NULL.) */ + if (simple->simple_data) + { + goo_canvas_grid_free_data (grid->grid_data); + g_slice_free (GooCanvasGridData, grid->grid_data); + } + grid->grid_data = NULL; + + G_OBJECT_CLASS (goo_canvas_grid_parent_class)->finalize (object); +} + + +static void +goo_canvas_grid_get_common_property (GObject *object, + GooCanvasGridData *grid_data, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_X: + g_value_set_double (value, grid_data->x); + break; + case PROP_Y: + g_value_set_double (value, grid_data->y); + break; + case PROP_WIDTH: + g_value_set_double (value, grid_data->width); + break; + case PROP_HEIGHT: + g_value_set_double (value, grid_data->height); + break; + case PROP_X_STEP: + g_value_set_double (value, grid_data->x_step); + break; + case PROP_Y_STEP: + g_value_set_double (value, grid_data->y_step); + break; + case PROP_X_OFFSET: + g_value_set_double (value, grid_data->x_offset); + break; + case PROP_Y_OFFSET: + g_value_set_double (value, grid_data->y_offset); + break; + case PROP_HORZ_GRID_LINE_WIDTH: + g_value_set_double (value, grid_data->horz_grid_line_width); + break; + case PROP_VERT_GRID_LINE_WIDTH: + g_value_set_double (value, grid_data->vert_grid_line_width); + break; + case PROP_HORZ_GRID_LINE_PATTERN: + g_value_set_boxed (value, grid_data->horz_grid_line_pattern); + break; + case PROP_VERT_GRID_LINE_PATTERN: + g_value_set_boxed (value, grid_data->vert_grid_line_pattern); + break; + case PROP_BORDER_WIDTH: + g_value_set_double (value, grid_data->border_width); + break; + case PROP_BORDER_PATTERN: + g_value_set_boxed (value, grid_data->border_pattern); + break; + case PROP_SHOW_HORZ_GRID_LINES: + g_value_set_boolean (value, grid_data->show_horz_grid_lines); + break; + case PROP_SHOW_VERT_GRID_LINES: + g_value_set_boolean (value, grid_data->show_vert_grid_lines); + break; + case PROP_VERT_GRID_LINES_ON_TOP: + g_value_set_boolean (value, grid_data->vert_grid_lines_on_top); + break; + + /* Convenience properties. */ + case PROP_HORZ_GRID_LINE_COLOR_RGBA: + goo_canvas_get_rgba_value_from_pattern (grid_data->horz_grid_line_pattern, value); + break; + case PROP_VERT_GRID_LINE_COLOR_RGBA: + goo_canvas_get_rgba_value_from_pattern (grid_data->vert_grid_line_pattern, value); + break; + case PROP_BORDER_COLOR_RGBA: + goo_canvas_get_rgba_value_from_pattern (grid_data->border_pattern, value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +goo_canvas_grid_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GooCanvasGrid *grid = (GooCanvasGrid*) object; + + goo_canvas_grid_get_common_property (object, grid->grid_data, + prop_id, value, pspec); +} + + +static void +goo_canvas_grid_set_common_property (GObject *object, + GooCanvasGridData *grid_data, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_X: + grid_data->x = g_value_get_double (value); + break; + case PROP_Y: + grid_data->y = g_value_get_double (value); + break; + case PROP_WIDTH: + grid_data->width = g_value_get_double (value); + break; + case PROP_HEIGHT: + grid_data->height = g_value_get_double (value); + break; + case PROP_X_STEP: + grid_data->x_step = g_value_get_double (value); + break; + case PROP_Y_STEP: + grid_data->y_step = g_value_get_double (value); + break; + case PROP_X_OFFSET: + grid_data->x_offset = g_value_get_double (value); + break; + case PROP_Y_OFFSET: + grid_data->y_offset = g_value_get_double (value); + break; + case PROP_HORZ_GRID_LINE_WIDTH: + grid_data->horz_grid_line_width = g_value_get_double (value); + break; + case PROP_VERT_GRID_LINE_WIDTH: + grid_data->vert_grid_line_width = g_value_get_double (value); + break; + case PROP_HORZ_GRID_LINE_PATTERN: + cairo_pattern_destroy (grid_data->horz_grid_line_pattern); + grid_data->horz_grid_line_pattern = g_value_get_boxed (value); + cairo_pattern_reference (grid_data->horz_grid_line_pattern); + break; + case PROP_VERT_GRID_LINE_PATTERN: + cairo_pattern_destroy (grid_data->vert_grid_line_pattern); + grid_data->vert_grid_line_pattern = g_value_get_boxed (value); + cairo_pattern_reference (grid_data->vert_grid_line_pattern); + break; + case PROP_BORDER_WIDTH: + grid_data->border_width = g_value_get_double (value); + break; + case PROP_BORDER_PATTERN: + cairo_pattern_destroy (grid_data->border_pattern); + grid_data->border_pattern = g_value_get_boxed (value); + cairo_pattern_reference (grid_data->border_pattern); + break; + case PROP_SHOW_HORZ_GRID_LINES: + grid_data->show_horz_grid_lines = g_value_get_boolean (value); + break; + case PROP_SHOW_VERT_GRID_LINES: + grid_data->show_vert_grid_lines = g_value_get_boolean (value); + break; + case PROP_VERT_GRID_LINES_ON_TOP: + grid_data->vert_grid_lines_on_top = g_value_get_boolean (value); + break; + + /* Convenience properties. */ + case PROP_HORZ_GRID_LINE_COLOR: + cairo_pattern_destroy (grid_data->horz_grid_line_pattern); + grid_data->horz_grid_line_pattern = goo_canvas_create_pattern_from_color_value (value); + break; + case PROP_HORZ_GRID_LINE_COLOR_RGBA: + cairo_pattern_destroy (grid_data->horz_grid_line_pattern); + grid_data->horz_grid_line_pattern = goo_canvas_create_pattern_from_rgba_value (value); + break; + case PROP_HORZ_GRID_LINE_PIXBUF: + cairo_pattern_destroy (grid_data->horz_grid_line_pattern); + grid_data->horz_grid_line_pattern = goo_canvas_create_pattern_from_pixbuf_value (value); + break; + + case PROP_VERT_GRID_LINE_COLOR: + cairo_pattern_destroy (grid_data->vert_grid_line_pattern); + grid_data->vert_grid_line_pattern = goo_canvas_create_pattern_from_color_value (value); + break; + case PROP_VERT_GRID_LINE_COLOR_RGBA: + cairo_pattern_destroy (grid_data->vert_grid_line_pattern); + grid_data->vert_grid_line_pattern = goo_canvas_create_pattern_from_rgba_value (value); + break; + case PROP_VERT_GRID_LINE_PIXBUF: + cairo_pattern_destroy (grid_data->vert_grid_line_pattern); + grid_data->vert_grid_line_pattern = goo_canvas_create_pattern_from_pixbuf_value (value); + break; + + case PROP_BORDER_COLOR: + cairo_pattern_destroy (grid_data->border_pattern); + grid_data->border_pattern = goo_canvas_create_pattern_from_color_value (value); + break; + case PROP_BORDER_COLOR_RGBA: + cairo_pattern_destroy (grid_data->border_pattern); + grid_data->border_pattern = goo_canvas_create_pattern_from_rgba_value (value); + break; + case PROP_BORDER_PIXBUF: + cairo_pattern_destroy (grid_data->border_pattern); + grid_data->border_pattern = goo_canvas_create_pattern_from_pixbuf_value (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +goo_canvas_grid_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object; + GooCanvasGrid *grid = (GooCanvasGrid*) object; + + if (simple->model) + { + g_warning ("Can't set property of a canvas item with a model - set the model property instead"); + return; + } + + goo_canvas_grid_set_common_property (object, grid->grid_data, + prop_id, value, pspec); + goo_canvas_item_simple_changed (simple, TRUE); +} + + +static void +goo_canvas_grid_update (GooCanvasItemSimple *simple, + cairo_t *cr) +{ + GooCanvasGrid *grid = (GooCanvasGrid*) simple; + GooCanvasGridData *grid_data = grid->grid_data; + gdouble border_width = 0.0; + + /* We can quickly compute the bounds as being just the grid's size + plus the border width around each edge. */ + if (grid_data->border_width > 0.0) + border_width = grid_data->border_width; + + simple->bounds.x1 = grid_data->x - border_width; + simple->bounds.y1 = grid_data->y - border_width; + simple->bounds.x2 = grid_data->x + grid_data->width + border_width; + simple->bounds.y2 = grid_data->y + grid_data->height + border_width; +} + + +static gdouble +calculate_start_position (gdouble start_pos, + gdouble step, + gdouble redraw_start_pos, + gdouble line_width) +{ + gdouble n = 0.0, result; + + /* We want the first position where pos + line_width/2 >= redraw_start_pos. + i.e. start_pos + (n * step) + (line_width / 2) >= redraw_start_pos, + or (n * step) >= redraw_start_pos - start_pos - (line_width / 2), + or n >= (redraw_start_pos - start_pos - (line_width / 2) / step). */ + if (step > 0.0) + n = ceil (((redraw_start_pos - start_pos - (line_width / 2.0))) / step); + + if (n <= 0.0) + result = start_pos; + else + result = start_pos + (n * step); + + return result; +} + + +static void +paint_vertical_lines (GooCanvasItemSimple *simple, + cairo_t *cr, + const GooCanvasBounds *bounds) +{ + GooCanvasItemSimpleData *simple_data = simple->simple_data; + GooCanvasGrid *grid = (GooCanvasGrid*) simple; + GooCanvasGridData *grid_data = grid->grid_data; + double x, max_x, max_y, max_bounds_x, line_width; + gboolean has_stroke; + + if (!grid_data->show_vert_grid_lines) + return; + + max_x = grid_data->x + grid_data->width; + max_y = grid_data->y + grid_data->height; + + has_stroke = goo_canvas_style_set_stroke_options (simple_data->style, cr); + line_width = goo_canvas_item_simple_get_line_width (simple); + + /* If the grid's vertical grid line pattern/color has been set, use that. + If not, and we don't have a stroke color just return. */ + if (grid_data->vert_grid_line_pattern) + cairo_set_source (cr, grid_data->vert_grid_line_pattern); + else if (!has_stroke) + return; + + /* If the grid's vertical grid line width has been set, use that. */ + if (grid_data->vert_grid_line_width > 0.0) + { + line_width = grid_data->vert_grid_line_width; + cairo_set_line_width (cr, line_width); + } + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + + /* Calculate the first grid line that intersects the bounds to redraw. */ + x = calculate_start_position (grid_data->x + grid_data->x_offset, + grid_data->x_step, bounds->x1, line_width); + + /* Calculate the last possible line position. */ + max_bounds_x = bounds->x2 + (line_width / 2.0); + max_x = MIN (max_x, max_bounds_x); + + /* Add on a tiny fraction of step to avoid any double comparison issues. */ + max_x += grid_data->x_step * 0.00001; + + while (x <= max_x) + { + cairo_move_to (cr, x, grid_data->y); + cairo_line_to (cr, x, max_y); + cairo_stroke (cr); + + /* Avoid an infinite loop. */ + if (grid_data->x_step <= 0.0) + break; + + x += grid_data->x_step; + } +} + + +static void +paint_horizontal_lines (GooCanvasItemSimple *simple, + cairo_t *cr, + const GooCanvasBounds *bounds) +{ + GooCanvasItemSimpleData *simple_data = simple->simple_data; + GooCanvasGrid *grid = (GooCanvasGrid*) simple; + GooCanvasGridData *grid_data = grid->grid_data; + double y, max_x, max_y, max_bounds_y, line_width; + gboolean has_stroke; + + if (!grid_data->show_horz_grid_lines) + return; + + max_x = grid_data->x + grid_data->width; + max_y = grid_data->y + grid_data->height; + + has_stroke = goo_canvas_style_set_stroke_options (simple_data->style, cr); + line_width = goo_canvas_item_simple_get_line_width (simple); + + /* If the grid's horizontal grid line pattern/color has been set, use that. + If not, and we don't have a stroke color just return. */ + if (grid_data->horz_grid_line_pattern) + cairo_set_source (cr, grid_data->horz_grid_line_pattern); + else if (!has_stroke) + return; + + /* If the grid's horizontal grid line width has been set, use that. */ + if (grid_data->horz_grid_line_width > 0.0) + { + line_width = grid_data->horz_grid_line_width; + cairo_set_line_width (cr, grid_data->horz_grid_line_width); + } + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + + /* Calculate the first grid line that intersects the bounds to redraw. */ + y = calculate_start_position (grid_data->y + grid_data->y_offset, + grid_data->y_step, bounds->y1, line_width); + + /* Calculate the last possible line position. */ + max_bounds_y = bounds->y2 + (line_width / 2.0); + max_y = MIN (max_y, max_bounds_y); + + /* Add on a tiny fraction of step to avoid any double comparison issues. */ + max_y += grid_data->y_step * 0.00001; + + while (y <= max_y) + { + cairo_move_to (cr, grid_data->x, y); + cairo_line_to (cr, max_x, y); + cairo_stroke (cr); + + /* Avoid an infinite loop. */ + if (grid_data->y_step <= 0.0) + break; + + y += grid_data->y_step; + } +} + + +static void +goo_canvas_grid_paint (GooCanvasItemSimple *simple, + cairo_t *cr, + const GooCanvasBounds *bounds) +{ + GooCanvasItemSimpleData *simple_data = simple->simple_data; + GooCanvasGrid *grid = (GooCanvasGrid*) simple; + GooCanvasGridData *grid_data = grid->grid_data; + GooCanvasBounds redraw_bounds = *bounds; + gdouble half_border_width; + + /* Paint the background in the fill pattern/color, if one is set. */ + if (goo_canvas_style_set_fill_options (simple_data->style, cr)) + { + cairo_rectangle (cr, grid_data->x, grid_data->y, + grid_data->width, grid_data->height); + cairo_fill (cr); + } + + /* Clip to the grid's area while painting the grid lines. */ + cairo_save (cr); + cairo_rectangle (cr, grid_data->x, grid_data->y, + grid_data->width, grid_data->height); + cairo_clip (cr); + + /* Convert the bounds to be redrawn from device space to item space. */ + goo_canvas_convert_bounds_to_item_space (simple->canvas, + (GooCanvasItem*) simple, + &redraw_bounds); + + /* Paint the grid lines, in the required order. */ + if (grid_data->vert_grid_lines_on_top) + { + paint_horizontal_lines (simple, cr, &redraw_bounds); + paint_vertical_lines (simple, cr, &redraw_bounds); + } + else + { + paint_vertical_lines (simple, cr, &redraw_bounds); + paint_horizontal_lines (simple, cr, &redraw_bounds); + } + + cairo_restore (cr); + + /* Paint the border. */ + if (grid_data->border_width > 0) + { + if (grid_data->border_pattern) + cairo_set_source (cr, grid_data->border_pattern); + else + goo_canvas_style_set_stroke_options (simple_data->style, cr); + + cairo_set_line_width (cr, grid_data->border_width); + half_border_width = grid_data->border_width / 2.0; + cairo_rectangle (cr, grid_data->x - half_border_width, + grid_data->y - half_border_width, + grid_data->width + grid_data->border_width, + grid_data->height + grid_data->border_width); + cairo_stroke (cr); + } +} + + +static void +goo_canvas_grid_set_model (GooCanvasItem *item, + GooCanvasItemModel *model) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; + GooCanvasGrid *grid = (GooCanvasGrid*) item; + GooCanvasGridModel *gmodel = (GooCanvasGridModel*) model; + + /* If our grid_data was allocated, free it. */ + if (!simple->model) + { + goo_canvas_grid_free_data (grid->grid_data); + g_slice_free (GooCanvasGridData, grid->grid_data); + } + + /* Now use the new model's grid_data instead. */ + grid->grid_data = &gmodel->grid_data; + + /* Let the parent class do the rest. */ + goo_canvas_grid_parent_iface->set_model (item, model); +} + + +static void +canvas_item_interface_init (GooCanvasItemIface *iface) +{ + iface->set_model = goo_canvas_grid_set_model; +} + + +static void +goo_canvas_grid_class_init (GooCanvasGridClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*) klass; + GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass; + + goo_canvas_grid_parent_iface = g_type_interface_peek (goo_canvas_grid_parent_class, GOO_TYPE_CANVAS_ITEM); + + gobject_class->finalize = goo_canvas_grid_finalize; + + gobject_class->get_property = goo_canvas_grid_get_property; + gobject_class->set_property = goo_canvas_grid_set_property; + + simple_class->simple_update = goo_canvas_grid_update; + simple_class->simple_paint = goo_canvas_grid_paint; + + goo_canvas_grid_install_common_properties (gobject_class); +} + + + +/** + * SECTION:goocanvasgridmodel + * @Title: GooCanvasGridModel + * @Short_Description: a model for grid items. + * + * GooCanvasGridModel represents a model for grid items. + * A grid consists of a number of equally-spaced horizontal and vertical + * grid lines, plus an optional border. + * + * It is a subclass of #GooCanvasItemModelSimple and so inherits all of the + * style properties such as "stroke-color", "fill-color" and "line-width". + * + * It also implements the #GooCanvasItemModel interface, so you can use the + * #GooCanvasItemModel functions such as goo_canvas_item_model_raise() and + * goo_canvas_item_model_rotate(). + * + * To create a #GooCanvasGridModel use goo_canvas_grid_model_new(). + * + * To get or set the properties of an existing #GooCanvasGridModel, use + * g_object_get() and g_object_set(). + * + * To respond to events such as mouse clicks on the grid you must connect + * to the signal handlers of the corresponding #GooCanvasGrid objects. + * (See goo_canvas_get_item() and #GooCanvas::item-created.) + * + * The grid's position and size is specified with the #GooCanvasGridModel:x, + * #GooCanvasGridModel:y, #GooCanvasGridModel:width and + * #GooCanvasGridModel:height properties. + * + * The #GooCanvasGridModel:x-step and #GooCanvasGridModel:y-step properties + * specify the distance between grid lines. The #GooCanvasGridModel:x-offset + * and #GooCanvasGridModel:y-offset properties specify the distance before the + * first grid lines. + * + * The horizontal or vertical grid lines can be hidden using the + * #GooCanvasGridModel:show-horz-grid-lines and + * #GooCanvasGridModel:show-vert-grid-lines properties. + * + * The width of the border can be set using the #GooCanvasGridModel:border-width + * property. The border is drawn outside the area specified with the + * #GooCanvasGridModel:x, #GooCanvasGridModel:y, #GooCanvasGridModel:width and + * #GooCanvasGridModel:height properties. + * + * Other properties allow the colors and widths of the grid lines to be set. + * The grid line color and width properties override the standard + * #GooCanvasItemModelSimple:stroke-color and + * #GooCanvasItemModelSimple:line-width properties, enabling different styles + * for horizontal and vertical grid lines. + */ + +GooCanvasItemModelIface *goo_canvas_grid_model_parent_iface; + +static void item_model_interface_init (GooCanvasItemModelIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GooCanvasGridModel, goo_canvas_grid_model, + GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE, + G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL, + item_model_interface_init)) + + +static void +goo_canvas_grid_model_init (GooCanvasGridModel *gmodel) +{ + goo_canvas_grid_init_data (&gmodel->grid_data); +} + + +/** + * goo_canvas_grid_model_new: + * @parent: the parent model, or %NULL. If a parent is specified, it will assume + * ownership of the item, and the item will automatically be freed when it is + * removed from the parent. Otherwise call g_object_unref() to free it. + * @x: the x coordinate of the left of the grid. + * @y: the y coordinate of the top of the grid. + * @width: the width of the grid. + * @height: the height of the grid. + * @x_step: the distance between the vertical grid lines. + * @y_step: the distance between the horizontal grid lines. + * @x_offset: the distance before the first vertical grid line. + * @y_offset: the distance before the first horizontal grid line. + * @...: optional pairs of property names and values, and a terminating %NULL. + * + * Creates a new grid model. + * + * + * + * Here's an example showing how to create a grid: + * + * + * GooCanvasItemModel *grid = goo_canvas_grid_model_new (mygroup, 100.0, 100.0, 400.0, 200.0, + * 20.0, 20.0, 10.0, 10.0, + * "horz-grid-line-width", 4.0, + * "horz-grid-line-color", "yellow", + * "vert-grid-line-width", 2.0, + * "vert-grid-line-color", "red", + * "border-width", 3.0, + * "border-color", "white", + * "fill-color", "blue", + * NULL); + * + * + * Returns: a new grid model. + **/ +GooCanvasItemModel* +goo_canvas_grid_model_new (GooCanvasItemModel *parent, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + gdouble x_step, + gdouble y_step, + gdouble x_offset, + gdouble y_offset, + ...) +{ + GooCanvasItemModel *model; + GooCanvasGridModel *gmodel; + GooCanvasGridData *grid_data; + const char *first_property; + va_list var_args; + + model = g_object_new (GOO_TYPE_CANVAS_GRID_MODEL, NULL); + gmodel = (GooCanvasGridModel*) model; + + grid_data = &gmodel->grid_data; + grid_data->x = x; + grid_data->y = y; + grid_data->width = width; + grid_data->height = height; + grid_data->x_step = x_step; + grid_data->y_step = y_step; + grid_data->x_offset = x_offset; + grid_data->y_offset = y_offset; + + va_start (var_args, y_offset); + first_property = va_arg (var_args, char*); + if (first_property) + g_object_set_valist ((GObject*) model, first_property, var_args); + va_end (var_args); + + if (parent) + { + goo_canvas_item_model_add_child (parent, model, -1); + g_object_unref (model); + } + + return model; +} + + +static void +goo_canvas_grid_model_finalize (GObject *object) +{ + GooCanvasGridModel *gmodel = (GooCanvasGridModel*) object; + + goo_canvas_grid_free_data (&gmodel->grid_data); + + G_OBJECT_CLASS (goo_canvas_grid_model_parent_class)->finalize (object); +} + + +static void +goo_canvas_grid_model_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GooCanvasGridModel *gmodel = (GooCanvasGridModel*) object; + + goo_canvas_grid_get_common_property (object, &gmodel->grid_data, + prop_id, value, pspec); +} + + +static void +goo_canvas_grid_model_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GooCanvasGridModel *gmodel = (GooCanvasGridModel*) object; + + goo_canvas_grid_set_common_property (object, &gmodel->grid_data, + prop_id, value, pspec); + g_signal_emit_by_name (gmodel, "changed", TRUE); +} + + +static GooCanvasItem* +goo_canvas_grid_model_create_item (GooCanvasItemModel *model, + GooCanvas *canvas) +{ + GooCanvasItem *item; + + item = g_object_new (GOO_TYPE_CANVAS_GRID, NULL); + goo_canvas_item_set_model (item, model); + + return item; +} + + +static void +item_model_interface_init (GooCanvasItemModelIface *iface) +{ + iface->create_item = goo_canvas_grid_model_create_item; +} + + +static void +goo_canvas_grid_model_class_init (GooCanvasGridModelClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*) klass; + + goo_canvas_grid_model_parent_iface = g_type_interface_peek (goo_canvas_grid_model_parent_class, GOO_TYPE_CANVAS_ITEM_MODEL); + + gobject_class->finalize = goo_canvas_grid_model_finalize; + + gobject_class->get_property = goo_canvas_grid_model_get_property; + gobject_class->set_property = goo_canvas_grid_model_set_property; + + goo_canvas_grid_install_common_properties (gobject_class); +} + + diff --git a/src/goocanvas/src/goocanvasgrid.h b/src/goocanvas/src/goocanvasgrid.h new file mode 100644 index 0000000..fa70e2e --- /dev/null +++ b/src/goocanvas/src/goocanvasgrid.h @@ -0,0 +1,153 @@ +/* + * GooCanvas. Copyright (C) 2005-8 Damon Chaplin. + * Released under the GNU LGPL license. See COPYING for details. + * + * goocanvasgrid.h - a grid item. + */ +#ifndef __GOO_CANVAS_GRID_H__ +#define __GOO_CANVAS_GRID_H__ + +#include +#include "goocanvasitemsimple.h" + +G_BEGIN_DECLS + + +/* This is the data used by both model and view classes. */ +typedef struct _GooCanvasGridData GooCanvasGridData; +struct _GooCanvasGridData +{ + /* The area that the grid covers. */ + gdouble x, y, width, height; + + /* The distance between grid lines. */ + gdouble x_step, y_step; + + /* The offset before the first grid line. */ + gdouble x_offset, y_offset; + + /* The widths of the grid lines, or -ve to use item's stroke width. */ + gdouble horz_grid_line_width, vert_grid_line_width; + + /* The color/pattern for the grid lines, or NULL to use the stroke color. */ + cairo_pattern_t *horz_grid_line_pattern, *vert_grid_line_pattern; + + /* The width of the border around the grid, or -1 for no border. */ + gdouble border_width; + + /* The color/pattern for the border, or NULL to use the stroke color. */ + cairo_pattern_t *border_pattern; + + /* If the horizontal and vertical grid lines should be shown. */ + guint show_horz_grid_lines : 1; + guint show_vert_grid_lines : 1; + + /* If vertical grid lines are drawn on top. */ + guint vert_grid_lines_on_top : 1; +}; + + +#define GOO_TYPE_CANVAS_GRID (goo_canvas_grid_get_type ()) +#define GOO_CANVAS_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_GRID, GooCanvasGrid)) +#define GOO_CANVAS_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_GRID, GooCanvasGridClass)) +#define GOO_IS_CANVAS_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_GRID)) +#define GOO_IS_CANVAS_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_GRID)) +#define GOO_CANVAS_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_GRID, GooCanvasGridClass)) + + +typedef struct _GooCanvasGrid GooCanvasGrid; +typedef struct _GooCanvasGridClass GooCanvasGridClass; + +/** + * GooCanvasGrid + * + * The #GooCanvasGrid-struct struct contains private data only. + */ +struct _GooCanvasGrid +{ + GooCanvasItemSimple parent_object; + + GooCanvasGridData *grid_data; +}; + +struct _GooCanvasGridClass +{ + GooCanvasItemSimpleClass parent_class; + + /*< private >*/ + + /* Padding for future expansion */ + void (*_goo_canvas_reserved1) (void); + void (*_goo_canvas_reserved2) (void); + void (*_goo_canvas_reserved3) (void); + void (*_goo_canvas_reserved4) (void); +}; + + +GType goo_canvas_grid_get_type (void) G_GNUC_CONST; +GooCanvasItem* goo_canvas_grid_new (GooCanvasItem *parent, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + gdouble x_step, + gdouble y_step, + gdouble x_offset, + gdouble y_offset, + ...); + + + +#define GOO_TYPE_CANVAS_GRID_MODEL (goo_canvas_grid_model_get_type ()) +#define GOO_CANVAS_GRID_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_GRID_MODEL, GooCanvasGridModel)) +#define GOO_CANVAS_GRID_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_GRID_MODEL, GooCanvasGridModelClass)) +#define GOO_IS_CANVAS_GRID_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_GRID_MODEL)) +#define GOO_IS_CANVAS_GRID_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_GRID_MODEL)) +#define GOO_CANVAS_GRID_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_GRID_MODEL, GooCanvasGridModelClass)) + + +typedef struct _GooCanvasGridModel GooCanvasGridModel; +typedef struct _GooCanvasGridModelClass GooCanvasGridModelClass; + +/** + * GooCanvasGridModel + * + * The #GooCanvasGridModel-struct struct contains private data only. + */ +struct _GooCanvasGridModel +{ + GooCanvasItemModelSimple parent_object; + + GooCanvasGridData grid_data; +}; + +struct _GooCanvasGridModelClass +{ + GooCanvasItemModelSimpleClass parent_class; + + /*< private >*/ + + /* Padding for future expansion */ + void (*_goo_canvas_reserved1) (void); + void (*_goo_canvas_reserved2) (void); + void (*_goo_canvas_reserved3) (void); + void (*_goo_canvas_reserved4) (void); +}; + + +GType goo_canvas_grid_model_get_type (void) G_GNUC_CONST; +GooCanvasItemModel* goo_canvas_grid_model_new (GooCanvasItemModel *parent, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + gdouble x_step, + gdouble y_step, + gdouble x_offset, + gdouble y_offset, + ...); + + +G_END_DECLS + +#endif /* __GOO_CANVAS_GRID_H__ */ diff --git a/src/goocanvas/src/goocanvasgroup.c b/src/goocanvas/src/goocanvasgroup.c index c668fb3..0f709ac 100644 --- a/src/goocanvas/src/goocanvasgroup.c +++ b/src/goocanvas/src/goocanvasgroup.c @@ -25,6 +25,9 @@ * goo_canvas_item_rotate(), and the properties such as "visibility" and * "pointer-events". * + * If the #GooCanvasGroup:width and #GooCanvasGroup:height properties are + * set to positive values then the group is clipped to the given size. + * * To create a #GooCanvasGroup use goo_canvas_group_new(). * * To get or set the properties of an existing #GooCanvasGroup, use @@ -40,9 +43,38 @@ #include "goocanvasmarshal.h" #include "goocanvasatk.h" +typedef struct _GooCanvasGroupPrivate GooCanvasGroupPrivate; +struct _GooCanvasGroupPrivate { + gdouble x; + gdouble y; + gdouble width; + gdouble height; +}; + +#define GOO_CANVAS_GROUP_GET_PRIVATE(group) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((group), GOO_TYPE_CANVAS_GROUP, GooCanvasGroupPrivate)) +#define GOO_CANVAS_GROUP_MODEL_GET_PRIVATE(group) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((group), GOO_TYPE_CANVAS_GROUP_MODEL, GooCanvasGroupPrivate)) + +enum { + PROP_0, + + PROP_X, + PROP_Y, + PROP_WIDTH, + PROP_HEIGHT +}; static void goo_canvas_group_dispose (GObject *object); static void goo_canvas_group_finalize (GObject *object); +static void goo_canvas_group_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void goo_canvas_group_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); static void canvas_item_interface_init (GooCanvasItemIface *iface); G_DEFINE_TYPE_WITH_CODE (GooCanvasGroup, goo_canvas_group, @@ -50,14 +82,53 @@ G_DEFINE_TYPE_WITH_CODE (GooCanvasGroup, goo_canvas_group, G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM, canvas_item_interface_init)) +static void +goo_canvas_group_install_common_properties (GObjectClass *gobject_class) +{ + g_object_class_install_property (gobject_class, PROP_X, + g_param_spec_double ("x", + "X", + _("The x coordinate of the group"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_Y, + g_param_spec_double ("y", + "Y", + _("The y coordinate of the group"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_WIDTH, + g_param_spec_double ("width", + _("Width"), + _("The width of the group, or -1 to use the default width"), + -G_MAXDOUBLE, + G_MAXDOUBLE, -1.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_HEIGHT, + g_param_spec_double ("height", + _("Height"), + _("The height of the group, or -1 to use the default height"), + -G_MAXDOUBLE, + G_MAXDOUBLE, -1.0, + G_PARAM_READWRITE)); +} static void goo_canvas_group_class_init (GooCanvasGroupClass *klass) { GObjectClass *gobject_class = (GObjectClass*) klass; + g_type_class_add_private (gobject_class, sizeof (GooCanvasGroupPrivate)); + gobject_class->dispose = goo_canvas_group_dispose; gobject_class->finalize = goo_canvas_group_finalize; + gobject_class->get_property = goo_canvas_group_get_property; + gobject_class->set_property = goo_canvas_group_set_property; /* Register our accessible factory, but only if accessibility is enabled. */ if (!ATK_IS_NO_OP_OBJECT_FACTORY (atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET))) @@ -66,13 +137,22 @@ goo_canvas_group_class_init (GooCanvasGroupClass *klass) GOO_TYPE_CANVAS_GROUP, goo_canvas_item_accessible_factory_get_type ()); } + + goo_canvas_group_install_common_properties (gobject_class); } static void goo_canvas_group_init (GooCanvasGroup *group) { + GooCanvasGroupPrivate* priv = GOO_CANVAS_GROUP_GET_PRIVATE (group); + group->items = g_ptr_array_sized_new (8); + + priv->x = 0.0; + priv->y = 0.0; + priv->width = -1.0; + priv->height = -1.0; } @@ -146,12 +226,113 @@ goo_canvas_group_finalize (GObject *object) } +/* Gets the private data to use, from the model or from the item itself. */ +static GooCanvasGroupPrivate* +goo_canvas_group_get_private (GooCanvasGroup *group) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) group; + + if (simple->model) + return GOO_CANVAS_GROUP_MODEL_GET_PRIVATE (simple->model); + else + return GOO_CANVAS_GROUP_GET_PRIVATE (group); +} + + +static void +goo_canvas_group_get_common_property (GObject *object, + GooCanvasGroupPrivate *priv, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_X: + g_value_set_double (value, priv->x); + break; + case PROP_Y: + g_value_set_double (value, priv->y); + break; + case PROP_WIDTH: + g_value_set_double (value, priv->width); + break; + case PROP_HEIGHT: + g_value_set_double (value, priv->height); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +goo_canvas_group_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GooCanvasGroup *group = (GooCanvasGroup*) object; + GooCanvasGroupPrivate *priv = goo_canvas_group_get_private (group); + + goo_canvas_group_get_common_property (object, priv, prop_id, value, pspec); +} + +static void +goo_canvas_group_set_common_property (GObject *object, + GooCanvasGroupPrivate *priv, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_X: + priv->x = g_value_get_double (value); + break; + case PROP_Y: + priv->y = g_value_get_double (value); + break; + case PROP_WIDTH: + priv->width = g_value_get_double (value); + break; + case PROP_HEIGHT: + priv->height = g_value_get_double (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +goo_canvas_group_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object; + GooCanvasGroup *group = (GooCanvasGroup*) object; + GooCanvasGroupPrivate *priv = goo_canvas_group_get_private (group); + + if (simple->model) + { + g_warning ("Can't set property of a canvas item with a model - set the model property instead"); + return; + } + + goo_canvas_group_set_common_property (object, priv, prop_id, value, pspec); + goo_canvas_item_simple_changed (simple, TRUE); +} + static void goo_canvas_group_add_child (GooCanvasItem *item, GooCanvasItem *child, gint position) { + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; GooCanvasGroup *group = (GooCanvasGroup*) item; + AtkObject *atk_obj, *child_atk_obj; g_object_ref (child); @@ -166,6 +347,16 @@ goo_canvas_group_add_child (GooCanvasItem *item, } goo_canvas_item_set_parent (child, item); + goo_canvas_item_set_is_static (child, simple->simple_data->is_static); + + /* Emit the "children_changed" ATK signal, if ATK is enabled. */ + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (item)); + if (!ATK_IS_NO_OP_OBJECT (atk_obj)) + { + child_atk_obj = atk_gobject_accessible_for_object (G_OBJECT (child)); + g_signal_emit_by_name (atk_obj, "children_changed::add", + position, child_atk_obj); + } goo_canvas_item_request_update (item); } @@ -186,7 +377,8 @@ goo_canvas_group_move_child (GooCanvasItem *item, if (simple->canvas) { goo_canvas_item_get_bounds (child, &bounds); - goo_canvas_request_redraw (simple->canvas, &bounds); + goo_canvas_request_item_redraw (simple->canvas, &bounds, + simple->simple_data->is_static); } goo_canvas_util_ptr_array_move (group->items, old_position, new_position); @@ -203,6 +395,7 @@ goo_canvas_group_remove_child (GooCanvasItem *item, GooCanvasGroup *group = (GooCanvasGroup*) item; GooCanvasItem *child; GooCanvasBounds bounds; + AtkObject *atk_obj, *child_atk_obj; g_return_if_fail (child_num < group->items->len); @@ -211,14 +404,24 @@ goo_canvas_group_remove_child (GooCanvasItem *item, if (simple->canvas) { goo_canvas_item_get_bounds (child, &bounds); - goo_canvas_request_redraw (simple->canvas, &bounds); + goo_canvas_request_item_redraw (simple->canvas, &bounds, + simple->simple_data->is_static); } - goo_canvas_item_set_parent (child, NULL); - g_object_unref (child); + /* Emit the "children_changed" ATK signal, if ATK is enabled. */ + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (item)); + if (!ATK_IS_NO_OP_OBJECT (atk_obj)) + { + child_atk_obj = atk_gobject_accessible_for_object (G_OBJECT (child)); + g_signal_emit_by_name (atk_obj, "children_changed::remove", + child_num, child_atk_obj); + } g_ptr_array_remove_index (group->items, child_num); + goo_canvas_item_set_parent (child, NULL); + g_object_unref (child); + goo_canvas_item_request_update (item); } @@ -238,7 +441,9 @@ goo_canvas_group_get_child (GooCanvasItem *item, { GooCanvasGroup *group = (GooCanvasGroup*) item; - return group->items->pdata[child_num]; + if (child_num < group->items->len) + return group->items->pdata[child_num]; + return NULL; } @@ -252,6 +457,9 @@ goo_canvas_group_set_canvas (GooCanvasItem *item, GooCanvasGroup *group = (GooCanvasGroup*) item; gint i; + if (simple->canvas == canvas) + return; + simple->canvas = canvas; /* Recursively set the canvas of all child items. */ @@ -264,6 +472,29 @@ goo_canvas_group_set_canvas (GooCanvasItem *item, static void +goo_canvas_group_set_is_static (GooCanvasItem *item, + gboolean is_static) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; + GooCanvasItemSimpleData *simple_data = simple->simple_data; + GooCanvasGroup *group = (GooCanvasGroup*) item; + gint i; + + if (simple_data->is_static == is_static) + return; + + simple_data->is_static = is_static; + + /* Recursively set the canvas of all child items. */ + for (i = 0; i < group->items->len; i++) + { + GooCanvasItem *item = group->items->pdata[i]; + goo_canvas_item_set_is_static (item, is_static); + } +} + + +static void on_model_child_added (GooCanvasGroupModel *model, gint position, GooCanvasGroup *group) @@ -353,6 +584,7 @@ goo_canvas_group_update (GooCanvasItem *item, { GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; GooCanvasGroup *group = (GooCanvasGroup*) item; + GooCanvasGroupPrivate *priv = goo_canvas_group_get_private (group); GooCanvasBounds child_bounds; gboolean initial_bounds = TRUE; gint i; @@ -372,35 +604,38 @@ goo_canvas_group_update (GooCanvasItem *item, cairo_save (cr); if (simple->simple_data->transform) - cairo_transform (cr, simple->simple_data->transform); + cairo_transform (cr, simple->simple_data->transform); + + cairo_translate (cr, priv->x, priv->y); for (i = 0; i < group->items->len; i++) - { - GooCanvasItem *child = group->items->pdata[i]; - - goo_canvas_item_update (child, entire_tree, cr, &child_bounds); - - /* If the child has non-empty bounds, compute the union. */ - if (child_bounds.x1 < child_bounds.x2 - && child_bounds.y1 < child_bounds.y2) - { - if (initial_bounds) - { - simple->bounds.x1 = child_bounds.x1; - simple->bounds.y1 = child_bounds.y1; - simple->bounds.x2 = child_bounds.x2; - simple->bounds.y2 = child_bounds.y2; - initial_bounds = FALSE; - } - else - { - simple->bounds.x1 = MIN (simple->bounds.x1, child_bounds.x1); - simple->bounds.y1 = MIN (simple->bounds.y1, child_bounds.y1); - simple->bounds.x2 = MAX (simple->bounds.x2, child_bounds.x2); - simple->bounds.y2 = MAX (simple->bounds.y2, child_bounds.y2); - } - } - } + { + GooCanvasItem *child = group->items->pdata[i]; + + goo_canvas_item_update (child, entire_tree, cr, &child_bounds); + + /* If the child has non-empty bounds, compute the union. */ + if (child_bounds.x1 < child_bounds.x2 + && child_bounds.y1 < child_bounds.y2) + { + if (initial_bounds) + { + simple->bounds.x1 = child_bounds.x1; + simple->bounds.y1 = child_bounds.y1; + simple->bounds.x2 = child_bounds.x2; + simple->bounds.y2 = child_bounds.y2; + initial_bounds = FALSE; + } + else + { + simple->bounds.x1 = MIN (simple->bounds.x1, child_bounds.x1); + simple->bounds.y1 = MIN (simple->bounds.y1, child_bounds.y1); + simple->bounds.x2 = MAX (simple->bounds.x2, child_bounds.x2); + simple->bounds.y2 = MAX (simple->bounds.y2, child_bounds.y2); + } + } + } + cairo_restore (cr); } @@ -420,6 +655,7 @@ goo_canvas_group_get_items_at (GooCanvasItem *item, GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; GooCanvasItemSimpleData *simple_data = simple->simple_data; GooCanvasGroup *group = (GooCanvasGroup*) item; + GooCanvasGroupPrivate *priv = goo_canvas_group_get_private (group); gboolean visible = parent_visible; int i; @@ -447,6 +683,8 @@ goo_canvas_group_get_items_at (GooCanvasItem *item, if (simple_data->transform) cairo_transform (cr, simple_data->transform); + cairo_translate (cr, priv->x, priv->y); + /* If the group has a clip path, check if the point is inside it. */ if (simple_data->clip_path_commands) { @@ -462,6 +700,19 @@ goo_canvas_group_get_items_at (GooCanvasItem *item, } } + if (priv->width > 0.0 && priv->height > 0.0) + { + double user_x = x, user_y = y; + + cairo_device_to_user (cr, &user_x, &user_y); + if (user_x < 0.0 || user_x >= priv->width + || user_y < 0.0 || user_y >= priv->height) + { + cairo_restore (cr); + return found_items; + } + } + /* Step up from the bottom of the children to the top, adding any items found to the start of the list. */ for (i = 0; i < group->items->len; i++) @@ -487,6 +738,7 @@ goo_canvas_group_paint (GooCanvasItem *item, GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; GooCanvasItemSimpleData *simple_data = simple->simple_data; GooCanvasGroup *group = (GooCanvasGroup*) item; + GooCanvasGroupPrivate *priv = goo_canvas_group_get_private (group); gint i; /* Skip the item if the bounds don't intersect the expose rectangle. */ @@ -505,6 +757,8 @@ goo_canvas_group_paint (GooCanvasItem *item, if (simple_data->transform) cairo_transform (cr, simple_data->transform); + cairo_translate (cr, priv->x, priv->y); + /* Clip with the group's clip path, if it is set. */ if (simple_data->clip_path_commands) { @@ -513,6 +767,12 @@ goo_canvas_group_paint (GooCanvasItem *item, cairo_clip (cr); } + if (priv->width > 0.0 && priv->height > 0.0) + { + cairo_rectangle (cr, 0.0, 0.0, priv->width, priv->height); + cairo_clip (cr); + } + for (i = 0; i < group->items->len; i++) { GooCanvasItem *child = group->items->pdata[i]; @@ -539,6 +799,7 @@ canvas_item_interface_init (GooCanvasItemIface *iface) iface->paint = goo_canvas_group_paint; iface->set_model = goo_canvas_group_set_model; + iface->set_is_static = goo_canvas_group_set_is_static; } @@ -574,6 +835,14 @@ canvas_item_interface_init (GooCanvasItemIface *iface) static void item_model_interface_init (GooCanvasItemModelIface *iface); static void goo_canvas_group_model_dispose (GObject *object); static void goo_canvas_group_model_finalize (GObject *object); +static void goo_canvas_group_model_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void goo_canvas_group_model_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); G_DEFINE_TYPE_WITH_CODE (GooCanvasGroupModel, goo_canvas_group_model, GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE, @@ -585,16 +854,27 @@ static void goo_canvas_group_model_class_init (GooCanvasGroupModelClass *klass) { GObjectClass *gobject_class = (GObjectClass*) klass; + g_type_class_add_private (gobject_class, sizeof (GooCanvasGroupPrivate)); gobject_class->dispose = goo_canvas_group_model_dispose; gobject_class->finalize = goo_canvas_group_model_finalize; + gobject_class->get_property = goo_canvas_group_model_get_property; + gobject_class->set_property = goo_canvas_group_model_set_property; + + goo_canvas_group_install_common_properties (gobject_class); } static void goo_canvas_group_model_init (GooCanvasGroupModel *gmodel) { + GooCanvasGroupPrivate *priv = GOO_CANVAS_GROUP_MODEL_GET_PRIVATE (gmodel); gmodel->children = g_ptr_array_sized_new (8); + + priv->x = 0.0; + priv->y = 0.0; + priv->width = -1.0; + priv->height = -1.0; } @@ -667,6 +947,28 @@ goo_canvas_group_model_finalize (GObject *object) G_OBJECT_CLASS (goo_canvas_group_model_parent_class)->finalize (object); } +static void goo_canvas_group_model_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GooCanvasGroupModel *model = (GooCanvasGroupModel*) object; + GooCanvasGroupPrivate *priv = GOO_CANVAS_GROUP_MODEL_GET_PRIVATE (model); + + goo_canvas_group_get_common_property (object, priv, prop_id, value, pspec); +} + +static void goo_canvas_group_model_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GooCanvasGroupModel *model = (GooCanvasGroupModel*) object; + GooCanvasGroupPrivate *priv = GOO_CANVAS_GROUP_MODEL_GET_PRIVATE (model); + + goo_canvas_group_set_common_property (object, priv, prop_id, value, pspec); + g_signal_emit_by_name (model, "changed", TRUE); +} extern void _goo_canvas_item_model_emit_child_added (GooCanvasItemModel *model, gint position); @@ -719,11 +1021,12 @@ goo_canvas_group_model_remove_child (GooCanvasItemModel *model, child = gmodel->children->pdata[child_num]; goo_canvas_item_model_set_parent (child, NULL); - g_object_unref (child); g_ptr_array_remove_index (gmodel->children, child_num); g_signal_emit_by_name (gmodel, "child-removed", child_num); + + g_object_unref (child); } @@ -742,7 +1045,9 @@ goo_canvas_group_model_get_child (GooCanvasItemModel *model, { GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model; - return gmodel->children->pdata[child_num]; + if (child_num < gmodel->children->len) + return gmodel->children->pdata[child_num]; + return NULL; } diff --git a/src/goocanvas/src/goocanvasitem.c b/src/goocanvas/src/goocanvasitem.c index 4e1e095..57db899 100644 --- a/src/goocanvas/src/goocanvasitem.c +++ b/src/goocanvas/src/goocanvasitem.c @@ -48,6 +48,8 @@ enum { GRAB_BROKEN_EVENT, CHILD_NOTIFY, ANIMATION_FINISHED, + SCROLL_EVENT, + QUERY_TOOLTIP, LAST_SIGNAL }; @@ -101,7 +103,7 @@ goo_canvas_item_base_init (gpointer g_iface) { static GObjectNotifyContext cpn_context = { 0, NULL, NULL }; static gboolean initialized = FALSE; - + if (!initialized) { GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); @@ -118,8 +120,9 @@ goo_canvas_item_base_init (gpointer g_iface) * GooCanvasItem::enter-notify-event * @item: the item that received the signal. * @target_item: the target of the event. - * @event: the event data, with coordinates translated to canvas - * coordinates. + * @event: the event data. The x & y fields contain the mouse position + * in the item's coordinate space. The x_root & y_root fields contain + * the same coordinates converted to the canvas coordinate space. * * Emitted when the mouse enters an item. * @@ -142,8 +145,9 @@ goo_canvas_item_base_init (gpointer g_iface) * GooCanvasItem::leave-notify-event * @item: the item that received the signal. * @target_item: the target of the event. - * @event: the event data, with coordinates translated to canvas - * coordinates. + * @event: the event data. The x & y fields contain the mouse position + * in the item's coordinate space. The x_root & y_root fields contain + * the same coordinates converted to the canvas coordinate space. * * Emitted when the mouse leaves an item. * @@ -166,8 +170,9 @@ goo_canvas_item_base_init (gpointer g_iface) * GooCanvasItem::motion-notify-event * @item: the item that received the signal. * @target_item: the target of the event. - * @event: the event data, with coordinates translated to canvas - * coordinates. + * @event: the event data. The x & y fields contain the mouse position + * in the item's coordinate space. The x_root & y_root fields contain + * the same coordinates converted to the canvas coordinate space. * * Emitted when the mouse moves within an item. * @@ -190,8 +195,9 @@ goo_canvas_item_base_init (gpointer g_iface) * GooCanvasItem::button-press-event * @item: the item that received the signal. * @target_item: the target of the event. - * @event: the event data, with coordinates translated to canvas - * coordinates. + * @event: the event data. The x & y fields contain the mouse position + * in the item's coordinate space. The x_root & y_root fields contain + * the same coordinates converted to the canvas coordinate space. * * Emitted when a mouse button is pressed in an item. * @@ -214,8 +220,9 @@ goo_canvas_item_base_init (gpointer g_iface) * GooCanvasItem::button-release-event * @item: the item that received the signal. * @target_item: the target of the event. - * @event: the event data, with coordinates translated to canvas - * coordinates. + * @event: the event data. The x & y fields contain the mouse position + * in the item's coordinate space. The x_root & y_root fields contain + * the same coordinates converted to the canvas coordinate space. * * Emitted when a mouse button is released in an item. * @@ -331,6 +338,37 @@ goo_canvas_item_base_init (gpointer g_iface) GOO_TYPE_CANVAS_ITEM, GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + /** + * GooCanvasItem::query-tooltip: + * @item: the item which received the signal. + * @x: the x coordinate of the mouse. + * @y: the y coordinate of the mouse. + * @keyboard_mode: %TRUE if the tooltip was triggered using the keyboard. + * @tooltip: a #GtkTooltip. + * + * Emitted when the mouse has paused over the item for a certain amount + * of time, or the tooltip was requested via the keyboard. + * + * Note that if @keyboard_mode is %TRUE, the values of @x and @y are + * undefined and should not be used. + * + * If the item wants to display a tooltip it should update @tooltip + * and return %TRUE. + * + * Returns: %TRUE if the item has set a tooltip to show. + */ + canvas_item_signals[QUERY_TOOLTIP] = + g_signal_new ("query-tooltip", + iface_type, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GooCanvasItemIface, query_tooltip), + goo_canvas_boolean_handled_accumulator, NULL, + goo_canvas_marshal_BOOLEAN__DOUBLE_DOUBLE_BOOLEAN_OBJECT, + G_TYPE_BOOLEAN, 4, + G_TYPE_DOUBLE, + G_TYPE_DOUBLE, + G_TYPE_BOOLEAN, + GTK_TYPE_TOOLTIP); /** * GooCanvasItem::grab-broken-event @@ -362,7 +400,7 @@ goo_canvas_item_base_init (gpointer g_iface) * @pspec: the #GParamSpec of the changed child property. * * Emitted for each child property that has changed. - * The signal's detail holds the property name. + * The signal's detail holds the property name. */ canvas_item_signals[CHILD_NOTIFY] = g_signal_new ("child_notify", @@ -374,7 +412,6 @@ goo_canvas_item_base_init (gpointer g_iface) G_TYPE_NONE, 1, G_TYPE_PARAM); - /** * GooCanvasItem::animation-finished * @item: the item that received the signal. @@ -392,6 +429,33 @@ goo_canvas_item_base_init (gpointer g_iface) G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + /** + * GooCanvasItem::scroll-event + * @item: the item that received the signal. + * @target_item: the target of the event. + * @event: the event data. The x & y fields contain the mouse position + * in the item's coordinate space. The x_root & y_root fields contain + * the same coordinates converted to the canvas coordinate space. + * + * Emitted when a button in the 4 to 7 range is pressed. Wheel mice are + * usually configured to generate button press events for buttons 4 and 5 + * when the wheel is turned in an item. + * + * Returns: %TRUE to stop the signal emission, or %FALSE to let it + * continue. + */ + canvas_item_signals[SCROLL_EVENT] = + g_signal_new ("scroll_event", + iface_type, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GooCanvasItemIface, + scroll_event), + goo_canvas_boolean_handled_accumulator, NULL, + goo_canvas_marshal_BOOLEAN__OBJECT_BOXED, + G_TYPE_BOOLEAN, 2, + GOO_TYPE_CANVAS_ITEM, + GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_object_interface_install_property (g_iface, g_param_spec_object ("parent", _("Parent"), @@ -452,6 +516,13 @@ goo_canvas_item_base_init (gpointer g_iface) FALSE, G_PARAM_READWRITE)); + g_object_interface_install_property (g_iface, + g_param_spec_string ("tooltip", + _("Tooltip"), + _("The tooltip to display for the item"), + NULL, + G_PARAM_READWRITE)); + _goo_canvas_style_init (); initialized = TRUE; @@ -462,9 +533,9 @@ goo_canvas_item_base_init (gpointer g_iface) /** * goo_canvas_item_get_canvas: * @item: a #GooCanvasItem. - * + * * Returns the #GooCanvas containing the given #GooCanvasItem. - * + * * Returns: the #GooCanvas. **/ GooCanvas* @@ -491,7 +562,7 @@ goo_canvas_item_get_canvas (GooCanvasItem *item) * goo_canvas_item_set_canvas: * @item: a #GooCanvasItem. * @canvas: a #GooCanvas - * + * * This function is only intended to be used when implementing new canvas * items, specifically container items such as #GooCanvasGroup. * @@ -514,7 +585,7 @@ goo_canvas_item_set_canvas (GooCanvasItem *item, * @child: the item to add. * @position: the position of the item, or -1 to place it last (at the top of * the stacking order). - * + * * Adds a child item to a container item at the given stack position. **/ void @@ -536,7 +607,7 @@ goo_canvas_item_add_child (GooCanvasItem *item, * @item: a container item. * @old_position: the current position of the child item. * @new_position: the new position of the child item. - * + * * Moves a child item to a new stack position within the container. **/ void @@ -556,7 +627,7 @@ goo_canvas_item_move_child (GooCanvasItem *item, * goo_canvas_item_remove_child: * @item: a container item. * @child_num: the position of the child item to remove. - * + * * Removes the child item at the given position. **/ void @@ -575,9 +646,9 @@ goo_canvas_item_remove_child (GooCanvasItem *item, * goo_canvas_item_find_child: * @item: a container item. * @child: the child item to find. - * + * * Attempts to find the given child item with the container's stack. - * + * * Returns: the position of the given @child item, or -1 if it isn't found. **/ gint @@ -602,9 +673,9 @@ goo_canvas_item_find_child (GooCanvasItem *item, /** * goo_canvas_item_is_container: * @item: an item. - * + * * Tests to see if the given item is a container. - * + * * Returns: %TRUE if the item is a container. **/ gboolean @@ -619,9 +690,9 @@ goo_canvas_item_is_container (GooCanvasItem *item) /** * goo_canvas_item_get_n_children: * @item: a container item. - * + * * Gets the number of children of the container. - * + * * Returns: the number of children. **/ gint @@ -637,10 +708,11 @@ goo_canvas_item_get_n_children (GooCanvasItem *item) * goo_canvas_item_get_child: * @item: a container item. * @child_num: the position of a child in the container's stack. - * + * * Gets the child item at the given stack position. - * - * Returns: the child item at the given stack position. + * + * Returns: the child item at the given stack position, or %NULL if @child_num + * is out of range. **/ GooCanvasItem* goo_canvas_item_get_child (GooCanvasItem *item, @@ -655,9 +727,9 @@ goo_canvas_item_get_child (GooCanvasItem *item, /** * goo_canvas_item_get_parent: * @item: an item. - * + * * Gets the parent of the given item. - * + * * Returns: the parent item, or %NULL if the item has no parent. **/ GooCanvasItem* @@ -673,7 +745,7 @@ goo_canvas_item_get_parent (GooCanvasItem *item) * goo_canvas_item_set_parent: * @item: an item. * @parent: the new parent item. - * + * * This function is only intended to be used when implementing new canvas * items (specifically container items such as #GooCanvasGroup). * It sets the parent of the child item. @@ -693,9 +765,52 @@ goo_canvas_item_set_parent (GooCanvasItem *item, /** - * goo_canvas_item_remove: + * goo_canvas_item_get_is_static: * @item: an item. + * + * Returns %TRUE if the item is static. Static items do not move or change + * size when the canvas is scrolled or the scale changes. * + * Returns: %TRUE if the item is static. + **/ +gboolean +goo_canvas_item_get_is_static (GooCanvasItem *item) +{ + GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item); + + if (iface->get_is_static) + return iface->get_is_static (item); + return FALSE; +} + + +/** + * goo_canvas_item_set_is_static: + * @item: an item. + * @is_static: if the item is static. + * + * Notifies the item that it is static. Static items do not move or change + * size when the canvas is scrolled or the scale changes. + * + * Container items such as #GooCanvasGroup should call this function when + * children are added, to notify children whether they are static or not. + * Containers should also pass on any changes in their own status to children. + **/ +void +goo_canvas_item_set_is_static (GooCanvasItem *item, + gboolean is_static) +{ + GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item); + + if (iface->set_is_static) + iface->set_is_static (item, is_static); +} + + +/** + * goo_canvas_item_remove: + * @item: an item. + * * Removes an item from its parent. If the item is in a canvas it will be * removed. * @@ -724,7 +839,7 @@ goo_canvas_item_remove (GooCanvasItem *item) * @item: an item. * @above: the item to raise @item above, or %NULL to raise @item to the top * of the stack. - * + * * Raises an item in the stacking order. **/ void @@ -767,7 +882,7 @@ goo_canvas_item_raise (GooCanvasItem *item, * @item: an item. * @below: the item to lower @item below, or %NULL to lower @item to the * bottom of the stack. - * + * * Lowers an item in the stacking order. **/ void @@ -809,9 +924,9 @@ goo_canvas_item_lower (GooCanvasItem *item, * goo_canvas_item_get_transform: * @item: an item. * @transform: the place to store the transform. - * + * * Gets the transformation matrix of an item. - * + * * Returns: %TRUE if a transform is set. **/ gboolean @@ -829,11 +944,11 @@ goo_canvas_item_get_transform (GooCanvasItem *item, * @item: an item. * @child: a child of @item. * @transform: the place to store the transform. - * + * * Gets the transformation matrix of an item combined with any special * transform needed for the given child. These special transforms are used * by layout items such as #GooCanvasTable. - * + * * Returns: %TRUE if a transform is set. **/ gboolean @@ -859,7 +974,7 @@ goo_canvas_item_get_transform_for_child (GooCanvasItem *item, * @item: an item. * @transform: the new transformation matrix, or %NULL to reset the * transformation to the identity matrix. - * + * * Sets the transformation matrix of an item. **/ void @@ -877,13 +992,13 @@ goo_canvas_item_set_transform (GooCanvasItem *item, * @y: returns the y coordinate of the origin of the item's coordinate space. * @scale: returns the scale of the item. * @rotation: returns the clockwise rotation of the item, in degrees (0-360). - * + * * This function can be used to get the position, scale and rotation of an * item, providing that the item has a simple transformation matrix * (e.g. set with goo_canvas_item_set_simple_transform(), or using a * combination of simple translate, scale and rotate operations). If the item * has a complex transformation matrix the results will be incorrect. - * + * * Returns: %TRUE if a transform is set. **/ gboolean @@ -932,7 +1047,7 @@ goo_canvas_item_get_simple_transform (GooCanvasItem *item, * @y: the y coordinate of the origin of the item's coordinate space. * @scale: the scale of the item. * @rotation: the clockwise rotation of the item, in degrees. - * + * * A convenience function to set the item's transformation matrix. **/ void @@ -957,7 +1072,7 @@ goo_canvas_item_set_simple_transform (GooCanvasItem *item, * @item: an item. * @tx: the amount to move the origin in the horizontal direction. * @ty: the amount to move the origin in the vertical direction. - * + * * Translates the origin of the item's coordinate system by the given amounts. **/ void @@ -979,7 +1094,7 @@ goo_canvas_item_translate (GooCanvasItem *item, * @item: an item. * @sx: the amount to scale the horizontal axis. * @sy: the amount to scale the vertical axis. - * + * * Scales the item's coordinate system by the given amounts. **/ void @@ -1002,7 +1117,7 @@ goo_canvas_item_scale (GooCanvasItem *item, * @degrees: the clockwise angle of rotation. * @cx: the x coordinate of the origin of the rotation. * @cy: the y coordinate of the origin of the rotation. - * + * * Rotates the item's coordinate system by the given amount, about the given * origin. **/ @@ -1030,7 +1145,7 @@ goo_canvas_item_rotate (GooCanvasItem *item, * @degrees: the skew angle. * @cx: the x coordinate of the origin of the skew transform. * @cy: the y coordinate of the origin of the skew transform. - * + * * Skews the item's coordinate system along the x axis by the given amount, * about the given origin. **/ @@ -1059,7 +1174,7 @@ goo_canvas_item_skew_x (GooCanvasItem *item, * @degrees: the skew angle. * @cx: the x coordinate of the origin of the skew transform. * @cy: the y coordinate of the origin of the skew transform. - * + * * Skews the item's coordinate system along the y axis by the given amount, * about the given origin. **/ @@ -1085,10 +1200,10 @@ goo_canvas_item_skew_y (GooCanvasItem *item, /** * goo_canvas_item_get_style: * @item: an item. - * + * * Gets the item's style. If the item doesn't have its own style it will return * its parent's style. - * + * * Returns: the item's style. **/ GooCanvasStyle* @@ -1104,7 +1219,7 @@ goo_canvas_item_get_style (GooCanvasItem *item) * goo_canvas_item_set_style: * @item: an item. * @style: a style. - * + * * Sets the item's style, by copying the properties from the given style. **/ void @@ -1342,7 +1457,7 @@ _goo_canvas_item_animate_internal (GooCanvasItem *item, * second). * @step_time: the time between each animation step, in milliseconds. * @type: specifies what happens when the animation finishes. - * + * * Animates an item from its current position to the given offsets, scale * and rotation. **/ @@ -1365,7 +1480,7 @@ goo_canvas_item_animate (GooCanvasItem *item, /** * goo_canvas_item_stop_animation: * @item: an item. - * + * * Stops any current animation for the given item, leaving it at its current * position. **/ @@ -1384,7 +1499,7 @@ goo_canvas_item_stop_animation (GooCanvasItem *item) /** * goo_canvas_item_request_update: * @item: a #GooCanvasItem. - * + * * This function is only intended to be used when implementing new canvas * items. * @@ -1407,7 +1522,7 @@ goo_canvas_item_request_update (GooCanvasItem *item) * goo_canvas_item_get_bounds: * @item: a #GooCanvasItem. * @bounds: a #GooCanvasBounds to return the bounds in. - * + * * Gets the bounds of the item. * * Note that the bounds includes the entire fill and stroke extents of the @@ -1434,12 +1549,12 @@ goo_canvas_item_get_bounds (GooCanvasItem *item, * @parent_is_visible: %TRUE if the parent item is visible (which * implies that all ancestors are also visible). * @found_items: the list of items found so far. - * + * * This function is only intended to be used when implementing new canvas * items, specifically container items such as #GooCanvasGroup. * * It gets the items at the given point. - * + * * Returns: the @found_items list, with any more found items added onto * the start of the list, leaving the top item first. **/ @@ -1465,7 +1580,7 @@ goo_canvas_item_get_items_at (GooCanvasItem *item, /** * goo_canvas_item_is_visible: * @item: a #GooCanvasItem. - * + * * Checks if the item is visible. * * This entails checking the item's own visibility setting, as well as those @@ -1473,7 +1588,7 @@ goo_canvas_item_get_items_at (GooCanvasItem *item, * * Note that the item may be scrolled off the screen and so may not * be actually visible to the user. - * + * * Returns: %TRUE if the item is visible. **/ gboolean @@ -1498,9 +1613,9 @@ goo_canvas_item_is_visible (GooCanvasItem *item) /** * goo_canvas_item_get_model: * @item: a #GooCanvasItem. - * + * * Gets the model of the given canvas item. - * + * * Returns: the item's model, or %NULL if it has no model. **/ GooCanvasItemModel* @@ -1516,7 +1631,7 @@ goo_canvas_item_get_model (GooCanvasItem *item) * goo_canvas_item_set_model: * @item: a #GooCanvasItem. * @model: a #GooCanvasItemModel. - * + * * Sets the model of the given canvas item. **/ void @@ -1533,7 +1648,7 @@ goo_canvas_item_set_model (GooCanvasItem *item, /** * goo_canvas_item_ensure_updated: * @item: a #GooCanvasItem. - * + * * This function is only intended to be used when implementing new canvas * items. * @@ -1557,7 +1672,7 @@ goo_canvas_item_ensure_updated (GooCanvasItem *item) * @entire_tree: if the entire subtree should be updated. * @cr: a cairo context. * @bounds: a #GooCanvasBounds to return the new bounds in. - * + * * This function is only intended to be used when implementing new canvas * items, specifically container items such as #GooCanvasGroup. * @@ -1579,10 +1694,10 @@ goo_canvas_item_update (GooCanvasItem *item, * goo_canvas_item_paint: * @item: a #GooCanvasItem. * @cr: a cairo context. - * @bounds: the bounds that need to be repainted. + * @bounds: the bounds that need to be repainted, in device space. * @scale: the scale to use to determine whether an item should be painted. * See #GooCanvasItem:visibility-threshold. - * + * * This function is only intended to be used when implementing new canvas * items, specifically container items such as #GooCanvasGroup. * @@ -1609,12 +1724,12 @@ goo_canvas_item_paint (GooCanvasItem *item, * @cr: a cairo context. * @requested_area: a #GooCanvasBounds to return the requested area in, in the * parent's coordinate space. - * + * * This function is only intended to be used when implementing new canvas * items, specifically layout items such as #GooCanvasTable. * * It gets the requested area of a child item. - * + * * Returns: %TRUE if the item should be allocated space. **/ gboolean @@ -1633,14 +1748,14 @@ goo_canvas_item_get_requested_area (GooCanvasItem *item, * @item: a #GooCanvasItem. * @cr: a cairo context. * @width: the width that the item may be allocated. - * + * * This function is only intended to be used when implementing new canvas * items, specifically layout items such as #GooCanvasTable. * * It gets the requested height of a child item, assuming it is allocated the * given width. This is useful for text items whose requested height may change * depending on the allocated width. - * + * * Returns: the requested height of the item, given the allocated width, * or %-1 if the item doesn't support this method or its height doesn't * change when allocated different widths. @@ -1671,7 +1786,7 @@ goo_canvas_item_get_requested_height (GooCanvasItem *item, * the device coordinate space. * @y_offset: the y offset of the allocated area from the requested area in * the device coordinate space. - * + * * This function is only intended to be used when implementing new canvas * items, specifically layout items such as #GooCanvasTable. * @@ -2014,7 +2129,7 @@ _goo_canvas_item_set_child_properties_internal (GObject *object, * @child: a child #GooCanvasItem. * @property_name: the name of the child property to get. * @value: a location to return the value. - * + * * Gets a child property of @child. **/ void @@ -2038,7 +2153,7 @@ goo_canvas_item_get_child_property (GooCanvasItem *item, * @child: a child #GooCanvasItem. * @property_name: the name of the child property to set. * @value: the value to set the property to. - * + * * Sets a child property of @child. **/ void @@ -2062,7 +2177,7 @@ goo_canvas_item_set_child_property (GooCanvasItem *item, * @child: a child #GooCanvasItem. * @var_args: pairs of property names and value pointers, and a terminating * %NULL. - * + * * Gets the values of one or more child properties of @child. **/ void @@ -2082,7 +2197,7 @@ goo_canvas_item_get_child_properties_valist (GooCanvasItem *item, * @item: a #GooCanvasItem. * @child: a child #GooCanvasItem. * @var_args: pairs of property names and values, and a terminating %NULL. - * + * * Sets the values of one or more child properties of @child. **/ void @@ -2102,7 +2217,7 @@ goo_canvas_item_set_child_properties_valist (GooCanvasItem *item, * @item: a #GooCanvasItem. * @child: a child #GooCanvasItem. * @...: pairs of property names and value pointers, and a terminating %NULL. - * + * * Gets the values of one or more child properties of @child. **/ void @@ -2111,7 +2226,7 @@ goo_canvas_item_get_child_properties (GooCanvasItem *item, ...) { va_list var_args; - + va_start (var_args, child); goo_canvas_item_get_child_properties_valist (item, child, var_args); va_end (var_args); @@ -2123,7 +2238,7 @@ goo_canvas_item_get_child_properties (GooCanvasItem *item, * @item: a #GooCanvasItem. * @child: a child #GooCanvasItem. * @...: pairs of property names and values, and a terminating %NULL. - * + * * Sets the values of one or more child properties of @child. **/ void @@ -2132,7 +2247,7 @@ goo_canvas_item_set_child_properties (GooCanvasItem *item, ...) { va_list var_args; - + va_start (var_args, child); goo_canvas_item_set_child_properties_valist (item, child, var_args); va_end (var_args); @@ -2145,11 +2260,11 @@ goo_canvas_item_set_child_properties (GooCanvasItem *item, * @iclass: a #GObjectClass * @property_id: the id for the property * @pspec: the #GParamSpec for the property - * + * * This function is only intended to be used when implementing new canvas * items, specifically layout container items such as #GooCanvasTable. * - * It installs a child property on a canvas item class. + * It installs a child property on a canvas item class. **/ void goo_canvas_item_class_install_child_property (GObjectClass *iclass, @@ -2203,7 +2318,7 @@ goo_canvas_item_class_find_child_property (GObjectClass *iclass, * goo_canvas_item_class_list_child_properties: * @iclass: a #GObjectClass * @n_properties: location to return the number of child properties found - * @returns: a newly allocated array of #GParamSpec*. The array must be + * @returns: a newly allocated array of #GParamSpec*. The array must be * freed with g_free(). * * This function is only intended to be used when implementing new canvas diff --git a/src/goocanvas/src/goocanvasitem.h b/src/goocanvas/src/goocanvasitem.h index 5ac307c..76c61ec 100644 --- a/src/goocanvas/src/goocanvasitem.h +++ b/src/goocanvas/src/goocanvasitem.h @@ -55,7 +55,6 @@ GType goo_canvas_bounds_get_type (void) G_GNUC_CONST; #define GOO_TYPE_CANVAS_ITEM (goo_canvas_item_get_type ()) #define GOO_CANVAS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_ITEM, GooCanvasItem)) -#define GOO_CANVAS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_ITEM, GooCanvasItemClass)) #define GOO_IS_CANVAS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_ITEM)) #define GOO_CANVAS_ITEM_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GOO_TYPE_CANVAS_ITEM, GooCanvasItemIface)) @@ -110,6 +109,8 @@ typedef struct _GooCanvasItem GooCanvasItem; * @get_style: gets the item's style. * @set_style: sets the item's style. * @is_visible: returns %TRUE if the item is currently visible. + * @get_is_static: returns %TRUE if the item is static. + * @set_is_static: notifies the item whether it is static or not. * @get_requested_height: returns the requested height of the item, * given a particular allocated width, using the parent's coordinate space. * @get_model: gets the model that the canvas item is viewing. @@ -126,7 +127,10 @@ typedef struct _GooCanvasItem GooCanvasItem; * @key_release_event: signal emitted when a key is released. * @grab_broken_event: signal emitted when a grab that the item has is lost. * @child_notify: signal emitted when a child property is changed. + * @query_tooltip: signal emitted to query the tooltip of an item. * @animation_finished: signal emitted when the item's animation has finished. + * @scroll_event: signal emitted when the mouse wheel is activated within + * the item. * * #GooCanvasItemIFace holds the virtual methods that make up the * #GooCanvasItem interface. @@ -271,28 +275,30 @@ struct _GooCanvasItemIface GdkEventGrabBroken *event); void (* child_notify) (GooCanvasItem *item, GParamSpec *pspec); - - /*< private >*/ - - /* We might use this in future to support tooltips. */ gboolean (* query_tooltip) (GooCanvasItem *item, gdouble x, gdouble y, gboolean keyboard_tooltip, - gpointer /*GtkTooltip*/ *tooltip); + GtkTooltip *tooltip); + + gboolean (* get_is_static) (GooCanvasItem *item); + void (* set_is_static) (GooCanvasItem *item, + gboolean is_static); void (* animation_finished) (GooCanvasItem *item, gboolean stopped); + gboolean (* scroll_event) (GooCanvasItem *item, + GooCanvasItem *target, + GdkEventScroll *event); + + /*< private >*/ + /* Padding for future expansion */ void (*_goo_canvas_reserved1) (void); void (*_goo_canvas_reserved2) (void); void (*_goo_canvas_reserved3) (void); void (*_goo_canvas_reserved4) (void); - void (*_goo_canvas_reserved5) (void); - void (*_goo_canvas_reserved6) (void); - void (*_goo_canvas_reserved7) (void); - void (*_goo_canvas_reserved8) (void); }; @@ -449,6 +455,9 @@ void goo_canvas_item_allocate_area (GooCanvasItem *item, gdouble x_offset, gdouble y_offset); +gboolean goo_canvas_item_get_is_static (GooCanvasItem *item); +void goo_canvas_item_set_is_static (GooCanvasItem *item, + gboolean is_static); /* diff --git a/src/goocanvas/src/goocanvasitemmodel.c b/src/goocanvas/src/goocanvasitemmodel.c index a2e559a..6f2de83 100644 --- a/src/goocanvas/src/goocanvasitemmodel.c +++ b/src/goocanvas/src/goocanvasitemmodel.c @@ -98,7 +98,7 @@ goo_canvas_item_model_base_init (gpointer g_iface) { static GObjectNotifyContext cpn_context = { 0, NULL, NULL }; static gboolean initialized = FALSE; - + if (!initialized) { GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); @@ -184,7 +184,7 @@ goo_canvas_item_model_base_init (gpointer g_iface) * @pspec: the #GParamSpec of the changed child property. * * Emitted for each child property that has changed. - * The signal's detail holds the property name. + * The signal's detail holds the property name. */ item_model_signals[CHILD_NOTIFY] = g_signal_new ("child_notify", @@ -213,6 +213,7 @@ goo_canvas_item_model_base_init (gpointer g_iface) G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + g_object_interface_install_property (g_iface, g_param_spec_object ("parent", _("Parent"), @@ -273,6 +274,13 @@ goo_canvas_item_model_base_init (gpointer g_iface) FALSE, G_PARAM_READWRITE)); + g_object_interface_install_property (g_iface, + g_param_spec_string ("tooltip", + _("Tooltip"), + _("The tooltip to display for the item"), + NULL, + G_PARAM_READWRITE)); + _goo_canvas_style_init (); initialized = TRUE; @@ -286,7 +294,7 @@ goo_canvas_item_model_base_init (gpointer g_iface) * @child: the child to add. * @position: the position of the child, or -1 to place it last (at the top of * the stacking order). - * + * * Adds a child at the given stack position. **/ void @@ -308,7 +316,7 @@ goo_canvas_item_model_add_child (GooCanvasItemModel *model, * @model: an item model. * @old_position: the current position of the child. * @new_position: the new position of the child. - * + * * Moves a child to a new stack position. **/ void @@ -328,7 +336,7 @@ goo_canvas_item_model_move_child (GooCanvasItemModel *model, * goo_canvas_item_model_remove_child: * @model: an item model. * @child_num: the position of the child to remove. - * + * * Removes the child at the given position. **/ void @@ -347,9 +355,9 @@ goo_canvas_item_model_remove_child (GooCanvasItemModel *model, * goo_canvas_item_model_find_child: * @model: an item model. * @child: the child to find. - * + * * Attempts to find the given child with the container's stack. - * + * * Returns: the position of the given @child, or -1 if it isn't found. **/ gint @@ -374,9 +382,9 @@ goo_canvas_item_model_find_child (GooCanvasItemModel *model, /** * goo_canvas_item_model_is_container: * @model: an item model. - * + * * Tests to see if the given item model is a container. - * + * * Returns: %TRUE if the item model is a container. **/ gboolean @@ -391,9 +399,9 @@ goo_canvas_item_model_is_container (GooCanvasItemModel *model) /** * goo_canvas_item_model_get_n_children: * @model: an item model. - * + * * Gets the number of children of the container. - * + * * Returns: the number of children. **/ gint @@ -409,10 +417,11 @@ goo_canvas_item_model_get_n_children (GooCanvasItemModel *model) * goo_canvas_item_model_get_child: * @model: an item model. * @child_num: the position of a child in the container's stack. - * + * * Gets the child at the given stack position. - * - * Returns: the child at the given stack position. + * + * Returns: the child at the given stack position, or %NULL if @child_num + * is out of range. **/ GooCanvasItemModel* goo_canvas_item_model_get_child (GooCanvasItemModel *model, @@ -427,9 +436,9 @@ goo_canvas_item_model_get_child (GooCanvasItemModel *model, /** * goo_canvas_item_model_get_parent: * @model: an item model. - * + * * Gets the parent of the given model. - * + * * Returns: the parent model, or %NULL if the model has no parent. **/ GooCanvasItemModel* @@ -443,7 +452,7 @@ goo_canvas_item_model_get_parent (GooCanvasItemModel *model) * goo_canvas_item_model_set_parent: * @model: an item model. * @parent: the new parent item model. - * + * * This function is only intended to be used when implementing new canvas * item models (specifically container models such as #GooCanvasGroupModel). * It sets the parent of the child model. @@ -465,7 +474,7 @@ goo_canvas_item_model_set_parent (GooCanvasItemModel *model, /** * goo_canvas_item_model_remove: * @model: an item model. - * + * * Removes a model from its parent. If the model is in a canvas it will be * removed. * @@ -494,7 +503,7 @@ goo_canvas_item_model_remove (GooCanvasItemModel *model) * @model: an item model. * @above: the item model to raise @model above, or %NULL to raise @model to the top * of the stack. - * + * * Raises a model in the stacking order. **/ void @@ -537,7 +546,7 @@ goo_canvas_item_model_raise (GooCanvasItemModel *model, * @model: an item model. * @below: the item model to lower @model below, or %NULL to lower @model to the * bottom of the stack. - * + * * Lowers a model in the stacking order. **/ void @@ -579,9 +588,9 @@ goo_canvas_item_model_lower (GooCanvasItemModel *model, * goo_canvas_item_model_get_transform: * @model: an item model. * @transform: the place to store the transform. - * + * * Gets the transformation matrix of an item model. - * + * * Returns: %TRUE if a transform is set. **/ gboolean @@ -599,7 +608,7 @@ goo_canvas_item_model_get_transform (GooCanvasItemModel *model, * @model: an item model. * @transform: the new transformation matrix, or %NULL to reset the * transformation to the identity matrix. - * + * * Sets the transformation matrix of an item model. **/ void @@ -617,13 +626,13 @@ goo_canvas_item_model_set_transform (GooCanvasItemModel *model, * @y: returns the y coordinate of the origin of the model's coordinate space. * @scale: returns the scale of the model. * @rotation: returns the clockwise rotation of the model, in degrees (0-360). - * + * * This function can be used to get the position, scale and rotation of an * item model, providing that the model has a simple transformation matrix * (e.g. set with goo_canvas_item_model_set_simple_transform(), or using a * combination of simple translate, scale and rotate operations). If the model * has a complex transformation matrix the results will be incorrect. - * + * * Returns: %TRUE if a transform is set. **/ gboolean @@ -672,7 +681,7 @@ goo_canvas_item_model_get_simple_transform (GooCanvasItemModel *model, * @y: the y coordinate of the origin of the model's coordinate space. * @scale: the scale of the model. * @rotation: the clockwise rotation of the model, in degrees. - * + * * A convenience function to set the item model's transformation matrix. **/ void @@ -697,7 +706,7 @@ goo_canvas_item_model_set_simple_transform (GooCanvasItemModel *model, * @model: an item model. * @tx: the amount to move the origin in the horizontal direction. * @ty: the amount to move the origin in the vertical direction. - * + * * Translates the origin of the model's coordinate system by the given amounts. **/ void @@ -719,7 +728,7 @@ goo_canvas_item_model_translate (GooCanvasItemModel *model, * @model: an item model. * @sx: the amount to scale the horizontal axis. * @sy: the amount to scale the vertical axis. - * + * * Scales the model's coordinate system by the given amounts. **/ void @@ -742,7 +751,7 @@ goo_canvas_item_model_scale (GooCanvasItemModel *model, * @degrees: the clockwise angle of rotation. * @cx: the x coordinate of the origin of the rotation. * @cy: the y coordinate of the origin of the rotation. - * + * * Rotates the model's coordinate system by the given amount, about the given * origin. **/ @@ -770,7 +779,7 @@ goo_canvas_item_model_rotate (GooCanvasItemModel *model, * @degrees: the skew angle. * @cx: the x coordinate of the origin of the skew transform. * @cy: the y coordinate of the origin of the skew transform. - * + * * Skews the model's coordinate system along the x axis by the given amount, * about the given origin. **/ @@ -799,7 +808,7 @@ goo_canvas_item_model_skew_x (GooCanvasItemModel *model, * @degrees: the skew angle. * @cx: the x coordinate of the origin of the skew transform. * @cy: the y coordinate of the origin of the skew transform. - * + * * Skews the model's coordinate system along the y axis by the given amount, * about the given origin. **/ @@ -825,10 +834,10 @@ goo_canvas_item_model_skew_y (GooCanvasItemModel *model, /** * goo_canvas_item_model_get_style: * @model: an item model. - * + * * Gets the model's style. If the model doesn't have its own style it will * return its parent's style. - * + * * Returns: the model's style. **/ GooCanvasStyle* @@ -844,7 +853,7 @@ goo_canvas_item_model_get_style (GooCanvasItemModel *model) * goo_canvas_item_model_set_style: * @model: an item model. * @style: a style. - * + * * Sets the model's style, by copying the properties from the given style. **/ void @@ -885,7 +894,7 @@ extern void _goo_canvas_item_animate_internal (GooCanvasItem *item, * second). * @step_time: the time between each animation step, in milliseconds. * @type: specifies what happens when the animation finishes. - * + * * Animates a model from its current position to the given offsets, scale * and rotation. **/ @@ -908,7 +917,7 @@ goo_canvas_item_model_animate (GooCanvasItemModel *model, /** * goo_canvas_item_model_stop_animation: * @model: an item model. - * + * * Stops any current animation for the given model, leaving it at its current * position. **/ @@ -939,7 +948,7 @@ extern void _goo_canvas_item_set_child_properties_internal (GObject *object, GOb * @child: a child #GooCanvasItemModel. * @property_name: the name of the child property to get. * @value: a location to return the value. - * + * * Gets a child property of @child. **/ void @@ -963,7 +972,7 @@ goo_canvas_item_model_get_child_property (GooCanvasItemModel *model, * @child: a child #GooCanvasItemModel. * @property_name: the name of the child property to set. * @value: the value to set the property to. - * + * * Sets a child property of @child. **/ void @@ -987,7 +996,7 @@ goo_canvas_item_model_set_child_property (GooCanvasItemModel *model, * @child: a child #GooCanvasItemModel. * @var_args: pairs of property names and value pointers, and a terminating * %NULL. - * + * * Gets the values of one or more child properties of @child. **/ void @@ -1007,7 +1016,7 @@ goo_canvas_item_model_get_child_properties_valist (GooCanvasItemModel *model, * @model: a #GooCanvasItemModel. * @child: a child #GooCanvasItemModel. * @var_args: pairs of property names and values, and a terminating %NULL. - * + * * Sets the values of one or more child properties of @child. **/ void @@ -1027,7 +1036,7 @@ goo_canvas_item_model_set_child_properties_valist (GooCanvasItemModel *model, * @model: a #GooCanvasItemModel. * @child: a child #GooCanvasItemModel. * @...: pairs of property names and value pointers, and a terminating %NULL. - * + * * Gets the values of one or more child properties of @child. **/ void @@ -1036,7 +1045,7 @@ goo_canvas_item_model_get_child_properties (GooCanvasItemModel *model, ...) { va_list var_args; - + va_start (var_args, child); goo_canvas_item_model_get_child_properties_valist (model, child, var_args); va_end (var_args); @@ -1048,7 +1057,7 @@ goo_canvas_item_model_get_child_properties (GooCanvasItemModel *model, * @model: a #GooCanvasItemModel. * @child: a child #GooCanvasItemModel. * @...: pairs of property names and values, and a terminating %NULL. - * + * * Sets the values of one or more child properties of @child. **/ void @@ -1057,7 +1066,7 @@ goo_canvas_item_model_set_child_properties (GooCanvasItemModel *model, ...) { va_list var_args; - + va_start (var_args, child); goo_canvas_item_model_set_child_properties_valist (model, child, var_args); va_end (var_args); @@ -1070,12 +1079,12 @@ goo_canvas_item_model_set_child_properties (GooCanvasItemModel *model, * @mclass: a #GObjectClass * @property_id: the id for the property * @pspec: the #GParamSpec for the property - * + * * This function is only intended to be used when implementing new canvas * item models, specifically layout container item models such as * #GooCanvasTableModel. * - * It installs a child property on a canvas item class. + * It installs a child property on a canvas item class. **/ void goo_canvas_item_model_class_install_child_property (GObjectClass *mclass, @@ -1130,7 +1139,7 @@ goo_canvas_item_model_class_find_child_property (GObjectClass *mclass, * goo_canvas_item_model_class_list_child_properties: * @mclass: a #GObjectClass * @n_properties: location to return the number of child properties found - * @returns: a newly allocated array of #GParamSpec*. The array must be + * @returns: a newly allocated array of #GParamSpec*. The array must be * freed with g_free(). * * This function is only intended to be used when implementing new canvas diff --git a/src/goocanvas/src/goocanvasitemmodel.h b/src/goocanvas/src/goocanvasitemmodel.h index ebdf179..c32f7ef 100644 --- a/src/goocanvas/src/goocanvasitemmodel.h +++ b/src/goocanvas/src/goocanvasitemmodel.h @@ -15,7 +15,6 @@ G_BEGIN_DECLS #define GOO_TYPE_CANVAS_ITEM_MODEL (goo_canvas_item_model_get_type ()) #define GOO_CANVAS_ITEM_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_ITEM_MODEL, GooCanvasItemModel)) -#define GOO_CANVAS_ITEM_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_ITEM_MODEL, GooCanvasItemModelClass)) #define GOO_IS_CANVAS_ITEM_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_ITEM_MODEL)) #define GOO_CANVAS_ITEM_MODEL_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GOO_TYPE_CANVAS_ITEM_MODEL, GooCanvasItemModelIface)) @@ -149,7 +148,6 @@ struct _GooCanvasItemModelIface void (*_goo_canvas_reserved5) (void); void (*_goo_canvas_reserved6) (void); void (*_goo_canvas_reserved7) (void); - void (*_goo_canvas_reserved8) (void); }; diff --git a/src/goocanvas/src/goocanvasitemsimple.c b/src/goocanvas/src/goocanvasitemsimple.c index ff5fbdb..46544ed 100644 --- a/src/goocanvas/src/goocanvasitemsimple.c +++ b/src/goocanvas/src/goocanvasitemsimple.c @@ -79,7 +79,8 @@ enum { PROP_DESCRIPTION, PROP_CAN_FOCUS, PROP_CLIP_PATH, - PROP_CLIP_FILL_RULE + PROP_CLIP_FILL_RULE, + PROP_TOOLTIP }; static gboolean accessibility_enabled = FALSE; @@ -287,6 +288,9 @@ goo_canvas_item_simple_install_common_properties (GObjectClass *gobject_class) g_object_class_override_property (gobject_class, PROP_CAN_FOCUS, "can-focus"); + g_object_class_override_property (gobject_class, PROP_TOOLTIP, + "tooltip"); + /** * GooCanvasItemSimple:clip-path * @@ -432,27 +436,6 @@ goo_canvas_item_simple_finalize (GObject *object) } -static guint -convert_color (double red, double green, double blue, double alpha) -{ - guint red_byte, green_byte, blue_byte, alpha_byte; - - red_byte = red * 256; - red_byte -= red_byte >> 8; - - green_byte = green * 256; - green_byte -= green_byte >> 8; - - blue_byte = blue * 256; - blue_byte -= blue_byte >> 8; - - alpha_byte = alpha * 256; - alpha_byte -= alpha_byte >> 8; - - return (red_byte << 24) + (green_byte << 16) + (blue_byte << 8) + alpha_byte; -} - - static void goo_canvas_item_simple_get_common_property (GObject *object, GooCanvasItemSimpleData *simple_data, @@ -465,9 +448,6 @@ goo_canvas_item_simple_get_common_property (GObject *object, GValue *svalue; gdouble line_width = 2.0; gchar *font = NULL; - cairo_pattern_t *pattern; - double red, green, blue, alpha; - guint rgba = 0; switch (prop_id) { @@ -539,29 +519,15 @@ goo_canvas_item_simple_get_common_property (GObject *object, /* Convenience properties. */ case PROP_STROKE_COLOR_RGBA: svalue = goo_canvas_style_get_property (style, goo_canvas_style_stroke_pattern_id); - if (svalue && svalue->data[0].v_pointer) - { - pattern = svalue->data[0].v_pointer; - if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID) - { - cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha); - rgba = convert_color (red, green, blue, alpha); - } - } - g_value_set_uint (value, rgba); + if (svalue) + goo_canvas_get_rgba_value_from_pattern (svalue->data[0].v_pointer, + value); break; case PROP_FILL_COLOR_RGBA: svalue = goo_canvas_style_get_property (style, goo_canvas_style_fill_pattern_id); - if (svalue && svalue->data[0].v_pointer) - { - pattern = svalue->data[0].v_pointer; - if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID) - { - cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha); - rgba = convert_color (red, green, blue, alpha); - } - } - g_value_set_uint (value, rgba); + if (svalue) + goo_canvas_get_rgba_value_from_pattern (svalue->data[0].v_pointer, + value); break; /* Other properties. */ @@ -583,6 +549,9 @@ goo_canvas_item_simple_get_common_property (GObject *object, case PROP_CLIP_FILL_RULE: g_value_set_enum (value, simple_data->clip_fill_rule); break; + case PROP_TOOLTIP: + g_value_set_string (value, simple_data->tooltip); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -630,10 +599,6 @@ goo_canvas_item_simple_set_common_property (GObject *object, GParamSpec *pspec) { GooCanvasStyle *style; - GdkColor color = { 0, 0, 0, 0, }; - guint rgba, red, green, blue, alpha; - GdkPixbuf *pixbuf; - cairo_surface_t *surface; cairo_pattern_t *pattern; gboolean recompute_bounds = FALSE; cairo_matrix_t *transform; @@ -722,74 +687,29 @@ goo_canvas_item_simple_set_common_property (GObject *object, /* Convenience properties. */ case PROP_STROKE_COLOR: - if (g_value_get_string (value)) - gdk_color_parse (g_value_get_string (value), &color); - pattern = cairo_pattern_create_rgb (color.red / 65535.0, - color.green / 65535.0, - color.blue / 65535.0); - g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN); - g_value_take_boxed (&tmpval, pattern); - goo_canvas_style_set_property (style, goo_canvas_style_stroke_pattern_id, &tmpval); - g_value_unset (&tmpval); + pattern = goo_canvas_create_pattern_from_color_value (value); + goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern); break; case PROP_STROKE_COLOR_RGBA: - rgba = g_value_get_uint (value); - red = (rgba >> 24) & 0xFF; - green = (rgba >> 16) & 0xFF; - blue = (rgba >> 8) & 0xFF; - alpha = (rgba) & 0xFF; - pattern = cairo_pattern_create_rgba (red / 255.0, green / 255.0, - blue / 255.0, alpha / 255.0); - g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN); - g_value_take_boxed (&tmpval, pattern); - goo_canvas_style_set_property (style, goo_canvas_style_stroke_pattern_id, &tmpval); - g_value_unset (&tmpval); + pattern = goo_canvas_create_pattern_from_rgba_value (value); + goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern); break; case PROP_STROKE_PIXBUF: - pixbuf = g_value_get_object (value); - surface = goo_canvas_cairo_surface_from_pixbuf (pixbuf); - pattern = cairo_pattern_create_for_surface (surface); - cairo_surface_destroy (surface); - cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); - g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN); - g_value_take_boxed (&tmpval, pattern); - goo_canvas_style_set_property (style, goo_canvas_style_stroke_pattern_id, &tmpval); - g_value_unset (&tmpval); + pattern = goo_canvas_create_pattern_from_pixbuf_value (value); + goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern); break; + case PROP_FILL_COLOR: - if (g_value_get_string (value)) - gdk_color_parse (g_value_get_string (value), &color); - pattern = cairo_pattern_create_rgb (color.red / 65535.0, - color.green / 65535.0, - color.blue / 65535.0); - g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN); - g_value_take_boxed (&tmpval, pattern); - goo_canvas_style_set_property (style, goo_canvas_style_fill_pattern_id, &tmpval); - g_value_unset (&tmpval); + pattern = goo_canvas_create_pattern_from_color_value (value); + goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern); break; case PROP_FILL_COLOR_RGBA: - rgba = g_value_get_uint (value); - red = (rgba >> 24) & 0xFF; - green = (rgba >> 16) & 0xFF; - blue = (rgba >> 8) & 0xFF; - alpha = (rgba) & 0xFF; - pattern = cairo_pattern_create_rgba (red / 255.0, green / 255.0, - blue / 255.0, alpha / 255.0); - g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN); - g_value_take_boxed (&tmpval, pattern); - goo_canvas_style_set_property (style, goo_canvas_style_fill_pattern_id, &tmpval); - g_value_unset (&tmpval); + pattern = goo_canvas_create_pattern_from_rgba_value (value); + goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern); break; case PROP_FILL_PIXBUF: - pixbuf = g_value_get_object (value); - surface = goo_canvas_cairo_surface_from_pixbuf (pixbuf); - pattern = cairo_pattern_create_for_surface (surface); - cairo_surface_destroy (surface); - cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); - g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN); - g_value_take_boxed (&tmpval, pattern); - goo_canvas_style_set_property (style, goo_canvas_style_fill_pattern_id, &tmpval); - g_value_unset (&tmpval); + pattern = goo_canvas_create_pattern_from_pixbuf_value (value); + goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern); break; /* Other properties. */ @@ -821,6 +741,9 @@ goo_canvas_item_simple_set_common_property (GObject *object, simple_data->clip_fill_rule = g_value_get_enum (value); recompute_bounds = TRUE; break; + case PROP_TOOLTIP: + simple_data->tooltip = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -930,6 +853,9 @@ void goo_canvas_item_simple_changed (GooCanvasItemSimple *item, gboolean recompute_bounds) { + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; + GooCanvasItemSimpleData *simple_data = simple->simple_data; + if (recompute_bounds) { item->need_entire_subtree_update = TRUE; @@ -945,7 +871,7 @@ goo_canvas_item_simple_changed (GooCanvasItemSimple *item, else { if (item->canvas) - goo_canvas_request_redraw (item->canvas, &item->bounds); + goo_canvas_request_item_redraw (item->canvas, &item->bounds, simple_data->is_static); } } @@ -1151,6 +1077,27 @@ goo_canvas_item_simple_is_visible (GooCanvasItem *item) } +static gboolean +goo_canvas_item_simple_get_is_static (GooCanvasItem *item) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; + GooCanvasItemSimpleData *simple_data = simple->simple_data; + + return simple_data->is_static; +} + + +static void +goo_canvas_item_simple_set_is_static (GooCanvasItem *item, + gboolean is_static) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; + GooCanvasItemSimpleData *simple_data = simple->simple_data; + + simple_data->is_static = is_static; +} + + /** * goo_canvas_item_simple_check_style: * @item: a #GooCanvasItemSimple. @@ -1258,7 +1205,7 @@ goo_canvas_item_simple_update (GooCanvasItem *item, if (entire_tree || simple->need_update) { /* Request a redraw of the existing bounds. */ - goo_canvas_request_redraw (simple->canvas, &simple->bounds); + goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static); cairo_save (cr); if (simple_data->transform) @@ -1285,7 +1232,7 @@ goo_canvas_item_simple_update (GooCanvasItem *item, cairo_restore (cr); /* Request a redraw of the new bounds. */ - goo_canvas_request_redraw (simple->canvas, &simple->bounds); + goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static); } *bounds = simple->bounds; @@ -1302,6 +1249,9 @@ goo_canvas_item_simple_get_requested_area (GooCanvasItem *item, cairo_matrix_t matrix; double x_offset, y_offset; + /* Request a redraw of the existing bounds. */ + goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static); + cairo_save (cr); if (simple_data->transform) cairo_transform (cr, simple_data->transform); @@ -1370,6 +1320,7 @@ goo_canvas_item_simple_allocate_area (GooCanvasItem *item, gdouble y_offset) { GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; + GooCanvasItemSimpleData *simple_data = simple->simple_data; /* Simple items can't resize at all, so we just adjust the bounds x & y positions here, and let the item be clipped if necessary. */ @@ -1377,6 +1328,9 @@ goo_canvas_item_simple_allocate_area (GooCanvasItem *item, simple->bounds.y1 += y_offset; simple->bounds.x2 += x_offset; simple->bounds.y2 += y_offset; + + /* Request a redraw of the new bounds. */ + goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static); } @@ -1542,6 +1496,26 @@ goo_canvas_item_simple_set_model_internal (GooCanvasItem *item, } +static gboolean +goo_canvas_item_simple_query_tooltip (GooCanvasItem *item, + gdouble x, + gdouble y, + gboolean keyboard_tip, + GtkTooltip *tooltip) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; + GooCanvasItemSimpleData *simple_data = simple->simple_data; + + if (simple_data->tooltip) + { + gtk_tooltip_set_markup (tooltip, simple_data->tooltip); + return TRUE; + } + + return FALSE; +} + + static void canvas_item_interface_init (GooCanvasItemIface *iface) { @@ -1562,9 +1536,13 @@ canvas_item_interface_init (GooCanvasItemIface *iface) iface->get_style = goo_canvas_item_simple_get_style; iface->set_style = goo_canvas_item_simple_set_style; iface->is_visible = goo_canvas_item_simple_is_visible; + iface->get_is_static = goo_canvas_item_simple_get_is_static; + iface->set_is_static = goo_canvas_item_simple_set_is_static; iface->get_model = goo_canvas_item_simple_get_model; iface->set_model = goo_canvas_item_simple_set_model_internal; + + iface->query_tooltip = goo_canvas_item_simple_query_tooltip; } @@ -1692,7 +1670,8 @@ goo_canvas_item_simple_get_path_bounds (GooCanvasItemSimple *item, * This function is intended to be used by subclasses of #GooCanvasItemSimple, * typically in their update() or get_requested_area() methods. * - * It converts the item's bounds to a bounding box in device space. + * It converts the item's bounds to a bounding box in the canvas (device) + * coordinate space. **/ void goo_canvas_item_simple_user_bounds_to_device (GooCanvasItemSimple *item, diff --git a/src/goocanvas/src/goocanvasitemsimple.h b/src/goocanvas/src/goocanvasitemsimple.h index 73486c8..39ad00f 100644 --- a/src/goocanvas/src/goocanvasitemsimple.h +++ b/src/goocanvas/src/goocanvasitemsimple.h @@ -22,6 +22,7 @@ G_BEGIN_DECLS * @transform: the transformation matrix of the item, or %NULL. * @clip_path_commands: an array of #GooCanvasPathCommand specifying the clip * path of the item, or %NULL. + * @tooltip: the item's tooltip. * @visibility_threshold: the threshold scale setting at which to show the item * (if the @visibility setting is set to %VISIBLE_ABOVE_THRESHOLD). * @visibility: the #GooCanvasItemVisibility setting specifying whether the @@ -32,6 +33,7 @@ G_BEGIN_DECLS * @own_style: if the item has its own style, rather than using its parent's. * @clip_fill_rule: the #cairo_fill_rule_t setting specifying the fill rule * used for the clip path. + * @is_static: if the item is static. * * This is the data common to both the model and view classes. */ @@ -41,9 +43,6 @@ struct _GooCanvasItemSimpleData GooCanvasStyle *style; cairo_matrix_t *transform; GArray *clip_path_commands; - - /*< private >*/ - /* We will store tooltips here in future. */ gchar *tooltip; /*< public >*/ @@ -53,10 +52,11 @@ struct _GooCanvasItemSimpleData guint can_focus : 1; guint own_style : 1; guint clip_fill_rule : 4; + guint is_static : 1; /*< private >*/ /* We might use this in future for a cache setting - never/always/visible. */ - guint cache_setting : 3; + guint cache_setting : 2; /* We might need this for tooltips in future. */ guint has_tooltip : 1; }; diff --git a/src/goocanvas/src/goocanvasmarshal.c b/src/goocanvas/src/goocanvasmarshal.c index 18beee7..da2931f 100644 --- a/src/goocanvas/src/goocanvasmarshal.c +++ b/src/goocanvas/src/goocanvasmarshal.c @@ -208,3 +208,48 @@ goo_canvas_marshal_BOOLEAN__OBJECT_BOXED (GClosure *closure, g_value_set_boolean (return_value, v_return); } +/* BOOLEAN:DOUBLE,DOUBLE,BOOLEAN,OBJECT (./goocanvasmarshal.list:8) */ +void +goo_canvas_marshal_BOOLEAN__DOUBLE_DOUBLE_BOOLEAN_OBJECT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__DOUBLE_DOUBLE_BOOLEAN_OBJECT) (gpointer data1, + gdouble arg_1, + gdouble arg_2, + gboolean arg_3, + gpointer arg_4, + gpointer data2); + register GMarshalFunc_BOOLEAN__DOUBLE_DOUBLE_BOOLEAN_OBJECT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 5); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__DOUBLE_DOUBLE_BOOLEAN_OBJECT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_double (param_values + 1), + g_marshal_value_peek_double (param_values + 2), + g_marshal_value_peek_boolean (param_values + 3), + g_marshal_value_peek_object (param_values + 4), + data2); + + g_value_set_boolean (return_value, v_return); +} + diff --git a/src/goocanvas/src/goocanvasmarshal.h b/src/goocanvas/src/goocanvasmarshal.h index 5a3a65d..fe94ec6 100644 --- a/src/goocanvas/src/goocanvasmarshal.h +++ b/src/goocanvas/src/goocanvasmarshal.h @@ -47,6 +47,14 @@ extern void goo_canvas_marshal_BOOLEAN__OBJECT_BOXED (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); +/* BOOLEAN:DOUBLE,DOUBLE,BOOLEAN,OBJECT (./goocanvasmarshal.list:8) */ +extern void goo_canvas_marshal_BOOLEAN__DOUBLE_DOUBLE_BOOLEAN_OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + G_END_DECLS #endif /* __goo_canvas_marshal_MARSHAL_H__ */ diff --git a/src/goocanvas/src/goocanvaspath.c b/src/goocanvas/src/goocanvaspath.c index d6af970..0254a66 100644 --- a/src/goocanvas/src/goocanvaspath.c +++ b/src/goocanvas/src/goocanvaspath.c @@ -33,26 +33,21 @@ #include #include #include "goocanvaspath.h" +#include "goocanvas.h" enum { PROP_0, PROP_DATA, + + PROP_X, + PROP_Y, + PROP_WIDTH, + PROP_HEIGHT }; static void canvas_item_interface_init (GooCanvasItemIface *iface); -static void goo_canvas_path_finalize (GObject *object); -static void goo_canvas_path_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); -static void goo_canvas_path_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); -static void goo_canvas_path_create_path (GooCanvasItemSimple *simple, - cairo_t *cr); G_DEFINE_TYPE_WITH_CODE (GooCanvasPath, goo_canvas_path, GOO_TYPE_CANVAS_ITEM_SIMPLE, @@ -76,23 +71,36 @@ goo_canvas_path_install_common_properties (GObjectClass *gobject_class) _("The sequence of path commands"), NULL, G_PARAM_WRITABLE)); -} - - -static void -goo_canvas_path_class_init (GooCanvasPathClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*) klass; - GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass; - - gobject_class->finalize = goo_canvas_path_finalize; - gobject_class->get_property = goo_canvas_path_get_property; - gobject_class->set_property = goo_canvas_path_set_property; - - simple_class->simple_create_path = goo_canvas_path_create_path; - - goo_canvas_path_install_common_properties (gobject_class); + g_object_class_install_property (gobject_class, PROP_X, + g_param_spec_double ("x", + "X", + _("The x coordinate of the path"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_Y, + g_param_spec_double ("y", + "Y", + _("The y coordinate of the path"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_WIDTH, + g_param_spec_double ("width", + _("Width"), + _("The width of the path"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_HEIGHT, + g_param_spec_double ("height", + _("Height"), + _("The height of the path"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); } @@ -200,16 +208,164 @@ goo_canvas_path_finalize (GObject *object) G_OBJECT_CLASS (goo_canvas_path_parent_class)->finalize (object); } +static void +goo_canvas_path_common_get_extent (GooCanvas *canvas, + GooCanvasPathData *path_data, + GooCanvasBounds *bounds) +{ + cairo_t *cr; + + cr = goo_canvas_create_cairo_context (canvas); + goo_canvas_create_path (path_data->path_commands, cr); + cairo_fill_extents (cr, &bounds->x1, &bounds->y1, &bounds->x2, &bounds->y2); + cairo_destroy (cr); +} + + +/* Moves all the absolute points in the command by the given amounts. + Relative points don't need to be moved. */ +static void +goo_canvas_path_move_command (GooCanvasPathCommand *cmd, + gdouble x_offset, + gdouble y_offset) +{ + switch (cmd->simple.type) + { + case GOO_CANVAS_PATH_MOVE_TO: + case GOO_CANVAS_PATH_CLOSE_PATH: + case GOO_CANVAS_PATH_LINE_TO: + case GOO_CANVAS_PATH_HORIZONTAL_LINE_TO: + case GOO_CANVAS_PATH_VERTICAL_LINE_TO: + if (!cmd->simple.relative) + { + cmd->simple.x += x_offset; + cmd->simple.y += y_offset; + } + break; + case GOO_CANVAS_PATH_CURVE_TO: + case GOO_CANVAS_PATH_SMOOTH_CURVE_TO: + case GOO_CANVAS_PATH_QUADRATIC_CURVE_TO: + case GOO_CANVAS_PATH_SMOOTH_QUADRATIC_CURVE_TO: + if (!cmd->curve.relative) + { + cmd->curve.x += x_offset; + cmd->curve.y += y_offset; + cmd->curve.x1 += x_offset; + cmd->curve.y1 += y_offset; + cmd->curve.x2 += x_offset; + cmd->curve.y2 += y_offset; + } + break; + case GOO_CANVAS_PATH_ELLIPTICAL_ARC: + if (!cmd->arc.relative) + { + cmd->arc.x += x_offset; + cmd->arc.y += y_offset; + } + break; + default: + g_assert_not_reached(); + break; + } +} + + +/* Scales all the points in the command by the given amounts. Absolute points + are scaled about the given origin. */ +static void +goo_canvas_path_scale_command (GooCanvasPathCommand *cmd, + gdouble x_origin, + gdouble y_origin, + gdouble x_scale, + gdouble y_scale) +{ + switch (cmd->simple.type) + { + case GOO_CANVAS_PATH_MOVE_TO: + case GOO_CANVAS_PATH_CLOSE_PATH: + case GOO_CANVAS_PATH_LINE_TO: + case GOO_CANVAS_PATH_HORIZONTAL_LINE_TO: + case GOO_CANVAS_PATH_VERTICAL_LINE_TO: + if (cmd->simple.relative) + { + cmd->simple.x *= x_scale; + cmd->simple.y *= y_scale; + } + else + { + cmd->simple.x = x_origin + (cmd->simple.x - x_origin) * x_scale; + cmd->simple.y = y_origin + (cmd->simple.y - y_origin) * y_scale; + } + break; + case GOO_CANVAS_PATH_CURVE_TO: + case GOO_CANVAS_PATH_SMOOTH_CURVE_TO: + case GOO_CANVAS_PATH_QUADRATIC_CURVE_TO: + case GOO_CANVAS_PATH_SMOOTH_QUADRATIC_CURVE_TO: + if (cmd->curve.relative) + { + cmd->curve.x *= x_scale; + cmd->curve.y *= y_scale; + cmd->curve.x1 *= x_scale; + cmd->curve.y1 *= y_scale; + cmd->curve.x2 *= x_scale; + cmd->curve.y2 *= y_scale; + } + else + { + cmd->curve.x = x_origin + (cmd->curve.x - x_origin) * x_scale; + cmd->curve.y = y_origin + (cmd->curve.y - y_origin) * y_scale; + cmd->curve.x1 = x_origin + (cmd->curve.x1 - x_origin) * x_scale; + cmd->curve.y1 = y_origin + (cmd->curve.y1 - y_origin) * y_scale; + cmd->curve.x2 = x_origin + (cmd->curve.x2 - x_origin) * x_scale; + cmd->curve.y2 = y_origin + (cmd->curve.y2 - y_origin) * y_scale; + } + break; + case GOO_CANVAS_PATH_ELLIPTICAL_ARC: + if (cmd->arc.relative) + { + cmd->arc.x *= x_scale; + cmd->arc.y *= y_scale; + } + else + { + cmd->arc.x = x_origin + (cmd->arc.x - x_origin) * x_scale; + cmd->arc.y = y_origin + (cmd->arc.y - y_origin) * y_scale; + } + break; + default: + g_assert_not_reached(); + break; + } +} static void goo_canvas_path_get_common_property (GObject *object, + GooCanvas *canvas, GooCanvasPathData *path_data, guint prop_id, GValue *value, GParamSpec *pspec) { + GooCanvasBounds extent; + switch (prop_id) { + case PROP_X: + goo_canvas_path_common_get_extent (canvas, path_data, &extent); + g_value_set_double (value, extent.x1); + break; + case PROP_Y: + goo_canvas_path_common_get_extent (canvas, path_data, &extent); + g_value_set_double (value, extent.y1); + break; + case PROP_WIDTH: + goo_canvas_path_common_get_extent (canvas, path_data, &extent); + g_value_set_double (value, extent.x2 - extent.x1); + break; + case PROP_HEIGHT: + goo_canvas_path_common_get_extent (canvas, path_data, &extent); + g_value_set_double (value, extent.y2 - extent.y1); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -223,26 +379,113 @@ goo_canvas_path_get_property (GObject *object, GValue *value, GParamSpec *pspec) { + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object; GooCanvasPath *path = (GooCanvasPath*) object; - goo_canvas_path_get_common_property (object, path->path_data, prop_id, - value, pspec); + goo_canvas_path_get_common_property (object, simple->canvas, + path->path_data, prop_id, value, pspec); } static void goo_canvas_path_set_common_property (GObject *object, + GooCanvas *canvas, GooCanvasPathData *path_data, guint prop_id, const GValue *value, GParamSpec *pspec) { + GooCanvasBounds extent; + GooCanvasPathCommand *cmd; + gdouble x_offset, y_offset, x_scale, y_scale; + guint i; + switch (prop_id) { case PROP_DATA: if (path_data->path_commands) g_array_free (path_data->path_commands, TRUE); path_data->path_commands = goo_canvas_parse_path_data (g_value_get_string (value)); + g_object_notify (object, "x"); + g_object_notify (object, "y"); + g_object_notify (object, "width"); + g_object_notify (object, "height"); + break; + case PROP_X: + if (path_data->path_commands->len > 0) + { + /* Calculate the x offset from the current position. */ + goo_canvas_path_common_get_extent (canvas, path_data, &extent); + x_offset = g_value_get_double (value) - extent.x1; + + /* Add the offset to all the absolute x coordinates. */ + for (i = 0; i < path_data->path_commands->len; i++) + { + cmd = &g_array_index (path_data->path_commands, + GooCanvasPathCommand, i); + goo_canvas_path_move_command (cmd, x_offset, 0.0); + } + g_object_notify (object, "data"); + } + break; + case PROP_Y: + if (path_data->path_commands->len > 0) + { + /* Calculate the y offset from the current position. */ + goo_canvas_path_common_get_extent (canvas, path_data, &extent); + y_offset = g_value_get_double (value) - extent.y1; + + /* Add the offset to all the absolute y coordinates. */ + for (i = 0; i < path_data->path_commands->len; i++) + { + cmd = &g_array_index (path_data->path_commands, + GooCanvasPathCommand, i); + goo_canvas_path_move_command (cmd, 0.0, y_offset); + } + g_object_notify (object, "data"); + } + break; + case PROP_WIDTH: + if (path_data->path_commands->len >= 2) + { + goo_canvas_path_common_get_extent (canvas, path_data, &extent); + if (extent.x2 - extent.x1 != 0.0) + { + /* Calculate the amount to scale the path. */ + x_scale = g_value_get_double (value) / (extent.x2 - extent.x1); + + /* Scale the x coordinates, relative to the left-most point. */ + for (i = 0; i < path_data->path_commands->len; i++) + { + cmd = &g_array_index (path_data->path_commands, + GooCanvasPathCommand, i); + goo_canvas_path_scale_command (cmd, extent.x1, 0.0, + x_scale, 1.0); + } + g_object_notify (object, "data"); + } + } + break; + case PROP_HEIGHT: + if (path_data->path_commands->len >= 2) + { + goo_canvas_path_common_get_extent (canvas, path_data, &extent); + if (extent.y2 - extent.y1 != 0.0) + { + /* Calculate the amount to scale the polyline. */ + y_scale = g_value_get_double (value) / (extent.y2 - extent.y1); + + /* Scale the y coordinates, relative to the top-most point. */ + for (i = 0; i < path_data->path_commands->len; i++) + { + cmd = &g_array_index (path_data->path_commands, + GooCanvasPathCommand, i); + goo_canvas_path_scale_command (cmd, 0.0, extent.y1, + 1.0, y_scale); + } + g_object_notify (object, "data"); + } + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -266,8 +509,8 @@ goo_canvas_path_set_property (GObject *object, return; } - goo_canvas_path_set_common_property (object, path->path_data, prop_id, - value, pspec); + goo_canvas_path_set_common_property (object, simple->canvas, path->path_data, + prop_id, value, pspec); goo_canvas_item_simple_changed (simple, TRUE); } @@ -282,6 +525,34 @@ goo_canvas_path_create_path (GooCanvasItemSimple *simple, } +static gboolean +goo_canvas_path_is_item_at (GooCanvasItemSimple *simple, + gdouble x, + gdouble y, + cairo_t *cr, + gboolean is_pointer_event) +{ + GooCanvasItemSimpleData *simple_data = simple->simple_data; + GooCanvasPointerEvents pointer_events = GOO_CANVAS_EVENTS_ALL; + gboolean do_fill; + + /* By default only check the fill if a fill color/pattern is specified. */ + do_fill = goo_canvas_style_set_fill_options (simple_data->style, cr); + if (!do_fill) + pointer_events &= ~GOO_CANVAS_EVENTS_FILL_MASK; + + /* If is_pointer_event is set use the pointer_events property instead. */ + if (is_pointer_event) + pointer_events = simple_data->pointer_events; + + goo_canvas_path_create_path (simple, cr); + if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events)) + return TRUE; + + return FALSE; +} + + static void goo_canvas_path_set_model (GooCanvasItem *item, GooCanvasItemModel *model) @@ -313,6 +584,24 @@ canvas_item_interface_init (GooCanvasItemIface *iface) } +static void +goo_canvas_path_class_init (GooCanvasPathClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*) klass; + GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass; + + gobject_class->finalize = goo_canvas_path_finalize; + + gobject_class->get_property = goo_canvas_path_get_property; + gobject_class->set_property = goo_canvas_path_set_property; + + simple_class->simple_create_path = goo_canvas_path_create_path; + simple_class->simple_is_item_at = goo_canvas_path_is_item_at; + + goo_canvas_path_install_common_properties (gobject_class); +} + + /** * SECTION:goocanvaspathmodel * @Title: GooCanvasPathModel @@ -478,8 +767,8 @@ goo_canvas_path_model_get_property (GObject *object, { GooCanvasPathModel *pmodel = (GooCanvasPathModel*) object; - goo_canvas_path_get_common_property (object, &pmodel->path_data, prop_id, - value, pspec); + goo_canvas_path_get_common_property (object, NULL, &pmodel->path_data, + prop_id, value, pspec); } @@ -491,8 +780,8 @@ goo_canvas_path_model_set_property (GObject *object, { GooCanvasPathModel *pmodel = (GooCanvasPathModel*) object; - goo_canvas_path_set_common_property (object, &pmodel->path_data, prop_id, - value, pspec); + goo_canvas_path_set_common_property (object, NULL, &pmodel->path_data, + prop_id, value, pspec); g_signal_emit_by_name (pmodel, "changed", TRUE); } diff --git a/src/goocanvas/src/goocanvaspolyline.c b/src/goocanvas/src/goocanvaspolyline.c index c78a2b7..94fc8c4 100644 --- a/src/goocanvas/src/goocanvaspolyline.c +++ b/src/goocanvas/src/goocanvaspolyline.c @@ -117,20 +117,16 @@ enum { PROP_END_ARROW, PROP_ARROW_LENGTH, PROP_ARROW_WIDTH, - PROP_ARROW_TIP_LENGTH + PROP_ARROW_TIP_LENGTH, + + PROP_X, + PROP_Y, + PROP_WIDTH, + PROP_HEIGHT }; -static void goo_canvas_polyline_finalize (GObject *object); static void canvas_item_interface_init (GooCanvasItemIface *iface); -static void goo_canvas_polyline_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); -static void goo_canvas_polyline_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); G_DEFINE_TYPE_WITH_CODE (GooCanvasPolyline, goo_canvas_polyline, GOO_TYPE_CANVAS_ITEM_SIMPLE, @@ -189,6 +185,36 @@ goo_canvas_polyline_install_common_properties (GObjectClass *gobject_class) _("The length of the arrow tip, as a multiple of the line width"), 0.0, G_MAXDOUBLE, 4.0, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_X, + g_param_spec_double ("x", + "X", + _("The x coordinate of the left-most point of the polyline"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_Y, + g_param_spec_double ("y", + "Y", + _("The y coordinate of the top-most point of the polyline"), + -G_MAXDOUBLE, + G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_WIDTH, + g_param_spec_double ("width", + _("Width"), + _("The width of the polyline"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_HEIGHT, + g_param_spec_double ("height", + _("Height"), + _("The height of the polyline"), + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); } @@ -221,6 +247,32 @@ goo_canvas_polyline_finalize (GObject *object) static void +goo_canvas_polyline_get_extent (GooCanvasPolylineData *polyline_data, + GooCanvasBounds *bounds) +{ + guint i; + + if (polyline_data->num_points == 0) + { + bounds->x1 = bounds->y1 = bounds->x2 = bounds->y2 = 0.0; + } + else + { + bounds->x1 = bounds->x2 = polyline_data->coords[0]; + bounds->y1 = bounds->y2 = polyline_data->coords[1]; + + for (i = 1; i < polyline_data->num_points; i++) + { + bounds->x1 = MIN (bounds->x1, polyline_data->coords[2 * i]); + bounds->y1 = MIN (bounds->y1, polyline_data->coords[2 * i + 1]); + bounds->x2 = MAX (bounds->x2, polyline_data->coords[2 * i]); + bounds->y2 = MAX (bounds->y2, polyline_data->coords[2 * i + 1]); + } + } +} + + +static void goo_canvas_polyline_get_common_property (GObject *object, GooCanvasPolylineData *polyline_data, guint prop_id, @@ -228,6 +280,7 @@ goo_canvas_polyline_get_common_property (GObject *object, GParamSpec *pspec) { GooCanvasPoints *points; + GooCanvasBounds extent; switch (prop_id) { @@ -266,6 +319,22 @@ goo_canvas_polyline_get_common_property (GObject *object, g_value_set_double (value, polyline_data->arrow_data ? polyline_data->arrow_data->arrow_tip_length : 4.0); break; + case PROP_X: + goo_canvas_polyline_get_extent (polyline_data, &extent); + g_value_set_double (value, extent.x1); + break; + case PROP_Y: + goo_canvas_polyline_get_extent (polyline_data, &extent); + g_value_set_double (value, extent.y1); + break; + case PROP_WIDTH: + goo_canvas_polyline_get_extent (polyline_data, &extent); + g_value_set_double (value, extent.x2 - extent.x1); + break; + case PROP_HEIGHT: + goo_canvas_polyline_get_extent (polyline_data, &extent); + g_value_set_double (value, extent.y2 - extent.y1); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -437,6 +506,9 @@ goo_canvas_polyline_set_common_property (GObject *object, GParamSpec *pspec) { GooCanvasPoints *points; + GooCanvasBounds extent; + gdouble x_offset, y_offset, x_scale, y_scale; + guint i; switch (prop_id) { @@ -461,6 +533,10 @@ goo_canvas_polyline_set_common_property (GObject *object, polyline_data->num_points * 2 * sizeof (double)); } polyline_data->reconfigure_arrows = TRUE; + g_object_notify (object, "x"); + g_object_notify (object, "y"); + g_object_notify (object, "width"); + g_object_notify (object, "height"); break; case PROP_CLOSE_PATH: polyline_data->close_path = g_value_get_boolean (value); @@ -489,6 +565,68 @@ goo_canvas_polyline_set_common_property (GObject *object, polyline_data->arrow_data->arrow_tip_length = g_value_get_double (value); polyline_data->reconfigure_arrows = TRUE; break; + case PROP_X: + if (polyline_data->num_points > 0) + { + /* Calculate the x offset from the current position. */ + goo_canvas_polyline_get_extent (polyline_data, &extent); + x_offset = g_value_get_double (value) - extent.x1; + + /* Add the offset to all the x coordinates. */ + for (i = 0; i < polyline_data->num_points; i++) + polyline_data->coords[2 * i] += x_offset; + + g_object_notify (object, "points"); + } + break; + case PROP_Y: + if (polyline_data->num_points > 0) + { + /* Calculate the y offset from the current position. */ + goo_canvas_polyline_get_extent (polyline_data, &extent); + y_offset = g_value_get_double (value) - extent.y1; + + /* Add the offset to all the y coordinates. */ + for (i = 0; i < polyline_data->num_points; i++) + polyline_data->coords[2 * i + 1] += y_offset; + + g_object_notify (object, "points"); + } + break; + case PROP_WIDTH: + if (polyline_data->num_points >= 2) + { + goo_canvas_polyline_get_extent (polyline_data, &extent); + if (extent.x2 - extent.x1 != 0.0) + { + /* Calculate the amount to scale the polyline. */ + x_scale = g_value_get_double (value) / (extent.x2 - extent.x1); + + /* Scale the x coordinates, relative to the left-most point. */ + for (i = 0; i < polyline_data->num_points; i++) + polyline_data->coords[2 * i] = extent.x1 + (polyline_data->coords[2 * i] - extent.x1) * x_scale; + + g_object_notify (object, "points"); + } + } + break; + case PROP_HEIGHT: + if (polyline_data->num_points >= 2) + { + goo_canvas_polyline_get_extent (polyline_data, &extent); + if (extent.y2 - extent.y1 != 0.0) + { + /* Calculate the amount to scale the polyline. */ + y_scale = g_value_get_double (value) / (extent.y2 - extent.y1); + + /* Scale the y coordinates, relative to the top-most point. */ + for (i = 0; i < polyline_data->num_points; i++) + polyline_data->coords[2 * i + 1] = extent.y1 + (polyline_data->coords[2 * i + 1] - extent.y1) * y_scale; + + g_object_notify (object, "points"); + } + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -769,6 +907,10 @@ goo_canvas_polyline_is_item_at (GooCanvasItemSimple *simple, if (is_pointer_event) pointer_events = simple_data->pointer_events; + /* If the path isn't closed, we never check the fill. */ + if (!(polyline_data->close_path && polyline_data->num_points > 2)) + pointer_events &= ~GOO_CANVAS_EVENTS_FILL_MASK; + goo_canvas_polyline_create_path (polyline, cr); if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events)) return TRUE; diff --git a/src/goocanvas/src/goocanvasprivate.h b/src/goocanvas/src/goocanvasprivate.h index 3e58377..423f37e 100644 --- a/src/goocanvas/src/goocanvasprivate.h +++ b/src/goocanvas/src/goocanvasprivate.h @@ -8,6 +8,7 @@ #define __GOO_CANVAS_PRIVATE_H__ #include +#include "goocanvasstyle.h" G_BEGIN_DECLS @@ -30,6 +31,22 @@ gint goo_canvas_util_ptr_array_find_index (GPtrArray *ptr_array, cairo_pattern_t* goo_canvas_cairo_pattern_from_pixbuf (GdkPixbuf *pixbuf); cairo_surface_t* goo_canvas_cairo_surface_from_pixbuf (GdkPixbuf *pixbuf); +guint goo_canvas_convert_colors_to_rgba (double red, + double green, + double blue, + double alpha); + +void goo_canvas_get_rgba_value_from_pattern (cairo_pattern_t *pattern, + GValue *value); + +void goo_canvas_set_style_property_from_pattern (GooCanvasStyle *style, + GQuark property_id, + cairo_pattern_t *pattern); + +cairo_pattern_t* goo_canvas_create_pattern_from_color_value (const GValue *value); +cairo_pattern_t* goo_canvas_create_pattern_from_rgba_value (const GValue *value); +cairo_pattern_t* goo_canvas_create_pattern_from_pixbuf_value (const GValue *value); + gboolean goo_canvas_boolean_handled_accumulator (GSignalInvocationHint *ihint, GValue *return_accu, diff --git a/src/goocanvas/src/goocanvasrect.c b/src/goocanvas/src/goocanvasrect.c index e899546..0af1021 100644 --- a/src/goocanvas/src/goocanvasrect.c +++ b/src/goocanvas/src/goocanvasrect.c @@ -360,7 +360,6 @@ goo_canvas_rect_create_path (GooCanvasItemSimple *simple, /* Draw the plain rectangle. */ cairo_rectangle (cr, rect_data->x, rect_data->y, rect_data->width, rect_data->height); - cairo_close_path (cr); } } diff --git a/src/goocanvas/src/goocanvastable.c b/src/goocanvas/src/goocanvastable.c index 8ff2fe0..d20240b 100644 --- a/src/goocanvas/src/goocanvastable.c +++ b/src/goocanvas/src/goocanvastable.c @@ -51,6 +51,8 @@ enum { PROP_0, + PROP_X, + PROP_Y, PROP_WIDTH, PROP_HEIGHT, PROP_ROW_SPACING, @@ -164,6 +166,10 @@ struct _GooCanvasTableLayoutData GooCanvasTableDimensionLayoutData *dldata[2]; GooCanvasTableChildLayoutData *children; + /* Position of the table */ + gdouble x; + gdouble y; + /* This is TRUE if we are rounding everything to the nearest integer. */ gboolean integer_layout; @@ -219,20 +225,11 @@ static void goo_canvas_table_install_common_properties (GObjectClass *gobject_class, InstallChildPropertyFunc install_child_property) { - g_object_class_install_property (gobject_class, PROP_WIDTH, - g_param_spec_double ("width", - _("Width"), - _("The requested width of the table, or -1 to use the default width"), - -G_MAXDOUBLE, - G_MAXDOUBLE, -1.0, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, PROP_HEIGHT, - g_param_spec_double ("height", - _("Height"), - _("The requested height of the table, or -1 to use the default height"), - -G_MAXDOUBLE, - G_MAXDOUBLE, -1.0, - G_PARAM_READWRITE)); + /* Override from GooCanvasGroup */ + g_object_class_override_property (gobject_class, PROP_X, "x"); + g_object_class_override_property (gobject_class, PROP_Y, "y"); + g_object_class_override_property (gobject_class, PROP_WIDTH, "width"); + g_object_class_override_property (gobject_class, PROP_HEIGHT, "height"); /* FIXME: Support setting individual row/col spacing. */ g_object_class_install_property (gobject_class, PROP_ROW_SPACING, @@ -292,101 +289,101 @@ goo_canvas_table_install_common_properties (GObjectClass *gobject_class, * Child properties. */ install_child_property (gobject_class, CHILD_PROP_LEFT_PADDING, - g_param_spec_double ("left-padding", - _("Left Padding"), + g_param_spec_double ("left-padding", + _("Left Padding"), _("Extra space to add to the left of the item"), 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_RIGHT_PADDING, - g_param_spec_double ("right-padding", - _("Right Padding"), + g_param_spec_double ("right-padding", + _("Right Padding"), _("Extra space to add to the right of the item"), 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_TOP_PADDING, - g_param_spec_double ("top-padding", - _("Top Padding"), + g_param_spec_double ("top-padding", + _("Top Padding"), _("Extra space to add above the item"), 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_BOTTOM_PADDING, - g_param_spec_double ("bottom-padding", - _("Bottom Padding"), + g_param_spec_double ("bottom-padding", + _("Bottom Padding"), _("Extra space to add below the item"), 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_X_ALIGN, - g_param_spec_double ("x-align", - _("X Align"), + g_param_spec_double ("x-align", + _("X Align"), _("The horizontal position of the item within its allocated space. 0.0 is left-aligned, 1.0 is right-aligned"), 0.0, 1.0, 0.5, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_Y_ALIGN, - g_param_spec_double ("y-align", - _("Y Align"), + g_param_spec_double ("y-align", + _("Y Align"), _("The vertical position of the item within its allocated space. 0.0 is top-aligned, 1.0 is bottom-aligned"), 0.0, 1.0, 0.5, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_ROW, - g_param_spec_uint ("row", - _("Row"), + g_param_spec_uint ("row", + _("Row"), _("The row to place the item in"), 0, 65535, 0, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_COLUMN, - g_param_spec_uint ("column", - _("Column"), + g_param_spec_uint ("column", + _("Column"), _("The column to place the item in"), 0, 65535, 0, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_ROWS, - g_param_spec_uint ("rows", - _("Rows"), + g_param_spec_uint ("rows", + _("Rows"), _("The number of rows that the item spans"), 0, 65535, 1, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_COLUMNS, - g_param_spec_uint ("columns", - _("Columns"), + g_param_spec_uint ("columns", + _("Columns"), _("The number of columns that the item spans"), 0, 65535, 1, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_X_EXPAND, - g_param_spec_boolean ("x-expand", - _("X Expand"), + g_param_spec_boolean ("x-expand", + _("X Expand"), _("If the item expands horizontally as the table expands"), FALSE, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_X_FILL, - g_param_spec_boolean ("x-fill", - _("X Fill"), + g_param_spec_boolean ("x-fill", + _("X Fill"), _("If the item fills all horizontal allocated space"), FALSE, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_X_SHRINK, - g_param_spec_boolean ("x-shrink", - _("X Shrink"), + g_param_spec_boolean ("x-shrink", + _("X Shrink"), _("If the item can shrink smaller than its requested size horizontally"), FALSE, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_Y_EXPAND, - g_param_spec_boolean ("y-expand", - _("Y Expand"), + g_param_spec_boolean ("y-expand", + _("Y Expand"), _("If the item expands vertically as the table expands"), FALSE, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_Y_FILL, - g_param_spec_boolean ("y-fill", - _("Y Fill"), + g_param_spec_boolean ("y-fill", + _("Y Fill"), _("If the item fills all vertical allocated space"), FALSE, G_PARAM_READWRITE)); install_child_property (gobject_class, CHILD_PROP_Y_SHRINK, - g_param_spec_boolean ("y-shrink", - _("Y Shrink"), + g_param_spec_boolean ("y-shrink", + _("Y Shrink"), _("If the item can shrink smaller than its requested size vertically"), FALSE, G_PARAM_READWRITE)); @@ -430,6 +427,9 @@ goo_canvas_table_init_data (GooCanvasTableData *table_data) table_data->children = g_array_new (0, 0, sizeof (GooCanvasTableChild)); table_data->layout_data = g_slice_new (GooCanvasTableLayoutData); + table_data->layout_data->x = 0.0; + table_data->layout_data->y = 0.0; + table_data->layout_data->children = NULL; for (d = 0; d < 2; d++) { @@ -473,7 +473,7 @@ goo_canvas_table_init (GooCanvasTable *table) * ownership of the item, and the item will automatically be freed when it is * removed from the parent. Otherwise call g_object_unref() to free it. * @...: optional pairs of property names and values, and a terminating %NULL. - * + * * Creates a new table item. * * @@ -483,13 +483,13 @@ goo_canvas_table_init (GooCanvasTable *table) * * * GooCanvasItem *table, *square, *circle, *triangle; - * + * * table = goo_canvas_table_new (root, * "row-spacing", 4.0, * "column-spacing", 4.0, * NULL); * goo_canvas_item_translate (table, 400, 200); - * + * * square = goo_canvas_rect_new (table, 0.0, 0.0, 50.0, 50.0, * "fill-color", "red", * NULL); @@ -497,7 +497,7 @@ goo_canvas_table_init (GooCanvasTable *table) * "row", 0, * "column", 0, * NULL); - * + * * circle = goo_canvas_ellipse_new (table, 0.0, 0.0, 25.0, 25.0, * "fill-color", "blue", * NULL); @@ -505,7 +505,7 @@ goo_canvas_table_init (GooCanvasTable *table) * "row", 0, * "column", 1, * NULL); - * + * * triangle = goo_canvas_polyline_new (table, TRUE, 3, * 25.0, 0.0, 0.0, 50.0, 50.0, 50.0, * "fill-color", "yellow", @@ -515,7 +515,7 @@ goo_canvas_table_init (GooCanvasTable *table) * "column", 2, * NULL); * - * + * * Returns: a new table item. **/ GooCanvasItem* @@ -572,6 +572,12 @@ goo_canvas_table_get_common_property (GObject *object, { switch (prop_id) { + case PROP_X: + g_value_set_double (value, table_data->layout_data->x); + break; + case PROP_Y: + g_value_set_double (value, table_data->layout_data->y); + break; case PROP_WIDTH: g_value_set_double (value, table_data->width); break; @@ -618,7 +624,7 @@ goo_canvas_table_get_property (GObject *object, GooCanvasTable *table = (GooCanvasTable*) object; goo_canvas_table_get_common_property (object, table->table_data, - prop_id, value, pspec); + prop_id, value, pspec); } @@ -633,6 +639,12 @@ goo_canvas_table_set_common_property (GObject *object, switch (prop_id) { + case PROP_X: + table_data->layout_data->x = g_value_get_double (value); + break; + case PROP_Y: + table_data->layout_data->y = g_value_get_double (value); + break; case PROP_WIDTH: table_data->width = g_value_get_double (value); break; @@ -1438,7 +1450,7 @@ goo_canvas_table_size_request_pass2 (GooCanvasTable *table, GooCanvasTableDimensionLayoutData *dldata = layout_data->dldata[d]; gdouble max_size = 0.0; gint i; - + if (table_data->dimensions[d].homogeneous) { /* Calculate the maximum row or column size. */ @@ -1464,11 +1476,11 @@ goo_canvas_table_size_request_pass3 (GooCanvasTable *table, GooCanvasTableDimensionLayoutData *dldata; GooCanvasTableChild *child; gint i, j; - + for (i = 0; i < table_data->children->len; i++) { child = &g_array_index (table_data->children, GooCanvasTableChild, i); - + if (layout_data->children[i].requested_size[HORZ] <= 0.0) continue; @@ -1488,7 +1500,7 @@ goo_canvas_table_size_request_pass3 (GooCanvasTable *table, if (j < end) total_space += dldata[j].spacing; } - + /* If we need to request more space for this child to fill its requisition, then divide up the needed space amongst the columns it spans, favoring expandable columns if any. */ @@ -1514,7 +1526,7 @@ goo_canvas_table_size_request_pass3 (GooCanvasTable *table, n_expand = child->size[d]; force_expand = TRUE; } - + if (layout_data->integer_layout) { for (j = start; j <= end; j++) @@ -1552,7 +1564,7 @@ goo_canvas_table_size_allocate_init (GooCanvasTable *table, GooCanvasTableDimension *dimension = &table_data->dimensions[d]; GooCanvasTableDimensionLayoutData *dldata = layout_data->dldata[d]; gint i; - + /* Set the initial allocation, by copying over the requisition. Also set the final expand & shrink flags. */ for (i = 0; i < dimension->size; i++) @@ -1570,7 +1582,7 @@ goo_canvas_table_size_allocate_pass1 (GooCanvasTable *table, GooCanvasTableDimensionLayoutData *dldata; gdouble total_size, size_to_allocate, natural_size, extra, old_extra; gint i, nexpand, nshrink; - + /* If we were allocated more space than we requested * then we have to expand any expandable rows and columns * to fill in the extra space. @@ -1620,7 +1632,7 @@ goo_canvas_table_size_allocate_pass1 (GooCanvasTable *table, size_to_allocate = total_size; for (i = 0; i + 1 < dimension->size; i++) size_to_allocate -= dldata[i].spacing; - + if (layout_data->integer_layout) { gint n_elements = dimension->size; @@ -1669,14 +1681,14 @@ goo_canvas_table_size_allocate_pass1 (GooCanvasTable *table, } } } - + /* Check to see if we were allocated less width than we requested, * then shrink until we fit the size give. */ if (natural_size > total_size) { gint total_nshrink = nshrink; - + extra = natural_size - total_size; while (total_nshrink > 0 && extra > 0) { @@ -1778,7 +1790,7 @@ goo_canvas_table_size_allocate_pass3 (GooCanvasTable *table, if (requested_width <= 0.0) continue; - + start_column = child->start[HORZ]; end_column = child->start[HORZ] + child->size[HORZ] - 1; x = columns[start_column].start + layout_data->children[i].start_pad[HORZ]; @@ -1800,7 +1812,7 @@ goo_canvas_table_size_allocate_pass3 (GooCanvasTable *table, if (layout_data->integer_layout) x = floor (x + 0.5); } - + if (!(child->flags[VERT] & GOO_CANVAS_TABLE_CHILD_FILL)) { height = MIN (max_height, requested_height); @@ -1929,11 +1941,14 @@ goo_canvas_table_get_requested_area (GooCanvasItem *item, GooCanvasItemSimpleData *simple_data = simple->simple_data; GooCanvasTable *table = (GooCanvasTable*) item; GooCanvasTableData *table_data = table->table_data; - GooCanvasTableLayoutData *layout_data; + GooCanvasTableLayoutData *layout_data = table_data->layout_data; GooCanvasTableDimensionLayoutData *rows, *columns; gdouble width = 0.0, height = 0.0; gint row, column, end; - + + /* Request a redraw of the existing bounds */ + goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static); + /* We reset the bounds to 0, just in case we are hidden or aren't allocated any area. */ simple->bounds.x1 = simple->bounds.x2 = 0.0; @@ -1950,6 +1965,8 @@ goo_canvas_table_get_requested_area (GooCanvasItem *item, if (simple_data->transform) cairo_transform (cr, simple_data->transform); + cairo_translate (cr, layout_data->x, layout_data->y); + /* Initialize the layout data, get the requested sizes of all children, and set the expand, shrink and empty flags. */ goo_canvas_table_init_layout_data (table); @@ -1961,7 +1978,6 @@ goo_canvas_table_get_requested_area (GooCanvasItem *item, goo_canvas_table_size_request_pass3 (table, HORZ); goo_canvas_table_size_request_pass2 (table, HORZ); - layout_data = table_data->layout_data; rows = layout_data->dldata[VERT]; columns = layout_data->dldata[HORZ]; @@ -1973,7 +1989,7 @@ goo_canvas_table_get_requested_area (GooCanvasItem *item, width += columns[column].spacing; } width += (layout_data->border_width + layout_data->border_spacing[HORZ] + layout_data->grid_line_width[VERT]) * 2.0; - + /* Save the natural size, so we know if we have to clip children. */ layout_data->natural_size[HORZ] = width; @@ -2046,6 +2062,8 @@ goo_canvas_table_get_requested_height (GooCanvasItem *item, if (simple_data->transform) cairo_transform (cr, simple_data->transform); + cairo_translate (cr, layout_data->x, layout_data->y); + /* Convert the width from the parent's coordinate space. Note that we only need to support a simple scale operation here. */ if (simple_data->transform) @@ -2129,12 +2147,14 @@ goo_canvas_table_allocate_area (GooCanvasItem *item, -(allocated_area->y1 - requested_area->y1)); if (simple_data->transform) cairo_transform (cr, simple_data->transform); + cairo_translate (cr, layout_data->x, layout_data->y); goo_canvas_table_update_requested_heights (item, cr); cairo_restore (cr); cairo_save (cr); if (simple_data->transform) cairo_transform (cr, simple_data->transform); + cairo_translate (cr, layout_data->x, layout_data->y); /* Calculate the table's bounds. */ simple->bounds.x1 = simple->bounds.y1 = 0.0; @@ -2154,6 +2174,8 @@ goo_canvas_table_allocate_area (GooCanvasItem *item, layout_data->children = NULL; cairo_restore (cr); + + goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static); } @@ -2193,6 +2215,7 @@ goo_canvas_table_paint (GooCanvasItem *item, { GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; GooCanvasItemSimpleData *simple_data = simple->simple_data; + GooCanvasStyle *style = simple_data->style; GooCanvasGroup *group = (GooCanvasGroup*) item; GooCanvasTable *table = (GooCanvasTable*) item; GooCanvasTableData *table_data = table->table_data; @@ -2210,7 +2233,8 @@ goo_canvas_table_paint (GooCanvasItem *item, gdouble frame_width, frame_height; gdouble line_start, line_end; gdouble spacing, half_spacing_before, half_spacing_after; - gboolean old_grid_line_visibility = FALSE, cur_grid_line_visibility; + gboolean old_grid_line_visibility = FALSE; + gboolean cur_grid_line_visibility; /* Skip the item if the bounds don't intersect the expose rectangle. */ if (simple->bounds.x1 > bounds->x2 || simple->bounds.x2 < bounds->x1 @@ -2227,6 +2251,7 @@ goo_canvas_table_paint (GooCanvasItem *item, cairo_save (cr); if (simple_data->transform) cairo_transform (cr, simple_data->transform); + cairo_translate (cr, layout_data->x, layout_data->y); /* Clip with the table's clip path, if it is set. */ if (simple_data->clip_path_commands) @@ -2249,10 +2274,6 @@ goo_canvas_table_paint (GooCanvasItem *item, frame_width = MAX (layout_data->allocated_size[HORZ], layout_data->natural_size[HORZ]); frame_height = MAX (layout_data->allocated_size[VERT], layout_data->natural_size[VERT]); - /* Save current line width, line cap etc. for drawing items after having - drawn grid lines */ - cairo_save (cr); - /* Draw border and grid lines */ if (check_clip) { @@ -2264,7 +2285,26 @@ goo_canvas_table_paint (GooCanvasItem *item, cairo_clip (cr); } - cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); + /* Save current line width, line cap etc. for drawing items after having + drawn grid lines */ + cairo_save (cr); + + /* Fill the table, if desired. */ + if (goo_canvas_style_set_fill_options (style, cr)) + { + cairo_rectangle (cr, + layout_data->border_width + vert_grid_line_width, + layout_data->border_width + horz_grid_line_width, + layout_data->allocated_size[HORZ] - 2 * (layout_data->border_width + vert_grid_line_width), + layout_data->allocated_size[VERT] - 2 * (layout_data->border_width + horz_grid_line_width)); + cairo_fill (cr); + } + + /* We use the style for the stroke color, but the line cap style and line + width are overridden here. */ + goo_canvas_style_set_stroke_options (style, cr); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); /* Horizontal grid lines */ if (horz_grid_line_width > 0.0) @@ -2320,7 +2360,7 @@ goo_canvas_table_paint (GooCanvasItem *item, old_grid_line_visibility = cur_grid_line_visibility; } } - + cairo_stroke (cr); } @@ -2444,7 +2484,7 @@ goo_canvas_table_paint (GooCanvasItem *item, for (j = start_row; j <= end_row; j++) if (rows[j].shrink) clip = TRUE; - + /* Only clip the child if it may have been shrunk. */ if (clip) { @@ -2515,6 +2555,7 @@ goo_canvas_table_get_items_at (GooCanvasItem *item, cairo_save (cr); if (simple_data->transform) cairo_transform (cr, simple_data->transform); + cairo_translate (cr, layout_data->x, layout_data->y); cairo_device_to_user (cr, &user_x, &user_y); @@ -2730,7 +2771,7 @@ goo_canvas_table_model_init (GooCanvasTableModel *tmodel) * assume ownership of the item, and the item will automatically be freed when * it is removed from the parent. Otherwise call g_object_unref() to free it. * @...: optional pairs of property names and values, and a terminating %NULL. - * + * * Creates a new table model. * * @@ -2772,7 +2813,7 @@ goo_canvas_table_model_init (GooCanvasTableModel *tmodel) * "column", 2, * NULL); * - * + * * Returns: a new table model. **/ GooCanvasItemModel* diff --git a/src/goocanvas/src/goocanvastext.c b/src/goocanvas/src/goocanvastext.c index 9a245cd..5b100ae 100644 --- a/src/goocanvas/src/goocanvastext.c +++ b/src/goocanvas/src/goocanvastext.c @@ -19,6 +19,10 @@ * #GooCanvasItem functions such as goo_canvas_item_raise() and * goo_canvas_item_rotate(). * + * The #GooCanvasText:width and #GooCanvasText:height properties specify the + * area of the item. If it exceeds that area because there is too much text, + * it is clipped. The properties can be set to -1 to disable clipping. + * * To create a #GooCanvasText use goo_canvas_text_new(). * * To get or set the properties of an existing #GooCanvasText, use @@ -30,6 +34,15 @@ #include "goocanvastext.h" #include "goocanvas.h" +typedef struct _GooCanvasTextPrivate GooCanvasTextPrivate; +struct _GooCanvasTextPrivate { + gdouble height; +}; + +#define GOO_CANVAS_TEXT_GET_PRIVATE(text) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((text), GOO_TYPE_CANVAS_TEXT, GooCanvasTextPrivate)) +#define GOO_CANVAS_TEXT_MODEL_GET_PRIVATE(text) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((text), GOO_TYPE_CANVAS_TEXT_MODEL, GooCanvasTextPrivate)) enum { PROP_0, @@ -37,6 +50,7 @@ enum { PROP_X, PROP_Y, PROP_WIDTH, + PROP_HEIGHT, PROP_TEXT, PROP_USE_MARKUP, PROP_ANCHOR, @@ -45,6 +59,15 @@ enum { PROP_WRAP }; +static PangoLayout* +goo_canvas_text_create_layout (GooCanvasItemSimpleData *simple_data, + GooCanvasTextData *text_data, + gdouble layout_width, + cairo_t *cr, + GooCanvasBounds *bounds, + gdouble *origin_x_return, + gdouble *origin_y_return); + static void goo_canvas_text_finalize (GObject *object); static void canvas_item_interface_init (GooCanvasItemIface *iface); static void goo_canvas_text_get_property (GObject *object, @@ -121,6 +144,15 @@ goo_canvas_text_install_common_properties (GObjectClass *gobject_class) G_MAXDOUBLE, -1.0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_HEIGHT, + g_param_spec_double ("height", + _("Height"), + _("The height to use to layout the text, or -1 to use the natural height"), + -G_MAXDOUBLE, + G_MAXDOUBLE, -1.0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_ANCHOR, g_param_spec_enum ("anchor", _("Anchor"), @@ -142,6 +174,8 @@ goo_canvas_text_install_common_properties (GObjectClass *gobject_class) static void goo_canvas_text_init (GooCanvasText *text) { + GooCanvasTextPrivate *priv = GOO_CANVAS_TEXT_GET_PRIVATE (text); + text->text_data = g_slice_new0 (GooCanvasTextData); text->text_data->width = -1.0; text->text_data->anchor = GTK_ANCHOR_NW; @@ -149,6 +183,8 @@ goo_canvas_text_init (GooCanvasText *text) text->text_data->wrap = PANGO_WRAP_WORD; text->layout_width = -1.0; + + priv->height = -1.0; } @@ -243,9 +279,23 @@ goo_canvas_text_finalize (GObject *object) } +/* Gets the private data to use, from the model or from the item itself. */ +static GooCanvasTextPrivate* +goo_canvas_text_get_private (GooCanvasText *text) +{ + GooCanvasItemSimple *simple = (GooCanvasItemSimple*) text; + + if (simple->model) + return GOO_CANVAS_TEXT_MODEL_GET_PRIVATE (simple->model); + else + return GOO_CANVAS_TEXT_GET_PRIVATE (text); +} + + static void goo_canvas_text_get_common_property (GObject *object, GooCanvasTextData *text_data, + GooCanvasTextPrivate *priv, guint prop_id, GValue *value, GParamSpec *pspec) @@ -261,6 +311,9 @@ goo_canvas_text_get_common_property (GObject *object, case PROP_WIDTH: g_value_set_double (value, text_data->width); break; + case PROP_HEIGHT: + g_value_set_double (value, priv->height); + break; case PROP_TEXT: g_value_set_string (value, text_data->text); break; @@ -293,15 +346,17 @@ goo_canvas_text_get_property (GObject *object, GParamSpec *pspec) { GooCanvasText *text = (GooCanvasText*) object; + GooCanvasTextPrivate *priv = goo_canvas_text_get_private (text); - goo_canvas_text_get_common_property (object, text->text_data, prop_id, - value, pspec); + goo_canvas_text_get_common_property (object, text->text_data, priv, + prop_id, value, pspec); } static void goo_canvas_text_set_common_property (GObject *object, GooCanvasTextData *text_data, + GooCanvasTextPrivate *priv, guint prop_id, const GValue *value, GParamSpec *pspec) @@ -317,6 +372,9 @@ goo_canvas_text_set_common_property (GObject *object, case PROP_WIDTH: text_data->width = g_value_get_double (value); break; + case PROP_HEIGHT: + priv->height = g_value_get_double (value); + break; case PROP_TEXT: g_free (text_data->text); text_data->text = g_value_dup_string (value); @@ -351,6 +409,7 @@ goo_canvas_text_set_property (GObject *object, { GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object; GooCanvasText *text = (GooCanvasText*) object; + GooCanvasTextPrivate *priv = goo_canvas_text_get_private (text); if (simple->model) { @@ -358,7 +417,7 @@ goo_canvas_text_set_property (GObject *object, return; } - goo_canvas_text_set_common_property (object, text->text_data, prop_id, + goo_canvas_text_set_common_property (object, text->text_data, priv, prop_id, value, pspec); goo_canvas_item_simple_changed (simple, TRUE); } @@ -409,7 +468,6 @@ goo_canvas_text_create_layout (GooCanvasItemSimpleData *simple_data, font_options = cairo_font_options_create (); cairo_font_options_set_hint_metrics (font_options, hint_metrics); - cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); pango_cairo_context_set_font_options (context, font_options); cairo_font_options_destroy (font_options); @@ -501,8 +559,8 @@ goo_canvas_text_create_layout (GooCanvasItemSimpleData *simple_data, } } - bounds->x2 = origin_x + logical_width; - bounds->y2 = origin_y + logical_height; + bounds->x2 = bounds->x1 + logical_width; + bounds->y2 = bounds->y1 + logical_height; /* Now adjust it to take into account the ink bounds. Calculate how far the ink rect extends outside each edge of the logical rect and adjust @@ -535,6 +593,7 @@ goo_canvas_text_update (GooCanvasItemSimple *simple, cairo_t *cr) { GooCanvasText *text = (GooCanvasText*) simple; + GooCanvasTextPrivate *priv = goo_canvas_text_get_private (text); PangoLayout *layout; /* Initialize the layout width to the text item's specified width property. @@ -547,6 +606,10 @@ goo_canvas_text_update (GooCanvasItemSimple *simple, text->layout_width, cr, &simple->bounds, NULL, NULL); g_object_unref (layout); + + /* If the height is set, use that. */ + if (priv->height > 0.0) + simple->bounds.y2 = simple->bounds.y1 + priv->height; } @@ -574,6 +637,7 @@ goo_canvas_text_is_item_at (GooCanvasItemSimple *simple, { GooCanvasItemSimpleData *simple_data = simple->simple_data; GooCanvasText *text = (GooCanvasText*) simple; + GooCanvasTextPrivate *priv = goo_canvas_text_get_private (text); PangoLayout *layout; GooCanvasBounds bounds; PangoLayoutIter *iter; @@ -592,6 +656,10 @@ goo_canvas_text_is_item_at (GooCanvasItemSimple *simple, && goo_canvas_text_is_unpainted (simple_data->style)) return FALSE; + /* Check if the point is outside the clipped height. */ + if (priv->height > 0.0 && y > priv->height) + return FALSE; + layout = goo_canvas_text_create_layout (simple_data, text->text_data, text->layout_width, cr, &bounds, &origin_x, &origin_y); @@ -644,6 +712,7 @@ goo_canvas_text_paint (GooCanvasItemSimple *simple, const GooCanvasBounds *bounds) { GooCanvasText *text = (GooCanvasText*) simple; + GooCanvasTextPrivate *priv = goo_canvas_text_get_private (text); PangoLayout *layout; GooCanvasBounds layout_bounds; gdouble origin_x, origin_y; @@ -659,8 +728,18 @@ goo_canvas_text_paint (GooCanvasItemSimple *simple, text->layout_width, cr, &layout_bounds, &origin_x, &origin_y); + cairo_save (cr); + + if (priv->height > 0.0) + { + cairo_rectangle (cr, origin_x, origin_y, + text->layout_width, priv->height); + cairo_clip (cr); + } cairo_move_to (cr, origin_x, origin_y); pango_cairo_show_layout (cr, layout); + + cairo_restore (cr); g_object_unref (layout); } @@ -673,6 +752,7 @@ goo_canvas_text_get_requested_height (GooCanvasItem *item, GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item; GooCanvasItemSimpleData *simple_data = simple->simple_data; GooCanvasText *text = (GooCanvasText*) item; + GooCanvasTextPrivate *priv = goo_canvas_text_get_private (text); PangoLayout *layout; gdouble height; @@ -693,15 +773,23 @@ goo_canvas_text_get_requested_height (GooCanvasItem *item, if (simple_data->transform) text->layout_width /= simple_data->transform->xx; - /* Create layout with given width. */ - layout = goo_canvas_text_create_layout (simple_data, text->text_data, - text->layout_width, cr, - &simple->bounds, NULL, NULL); - g_object_unref (layout); + if (priv->height < 0.0) + { + /* Create layout with given width. */ + layout = goo_canvas_text_create_layout (simple_data, text->text_data, + text->layout_width, cr, + &simple->bounds, NULL, NULL); + g_object_unref (layout); + + height = simple->bounds.y2 - simple->bounds.y1; + } + else + { + height = priv->height; + } - /* Convert to the parent's coordinate space. As above, we only need to + /* Convert to the parent's coordinate space. As above, we only need to support a simple scale operation here. */ - height = simple->bounds.y2 - simple->bounds.y1; if (simple_data->transform) height *= simple_data->transform->yy; @@ -783,6 +871,8 @@ goo_canvas_text_class_init (GooCanvasTextClass *klass) GObjectClass *gobject_class = (GObjectClass*) klass; GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass; + g_type_class_add_private (gobject_class, sizeof (GooCanvasTextPrivate)); + gobject_class->finalize = goo_canvas_text_finalize; gobject_class->get_property = goo_canvas_text_get_property; @@ -843,6 +933,8 @@ goo_canvas_text_model_class_init (GooCanvasTextModelClass *klass) { GObjectClass *gobject_class = (GObjectClass*) klass; + g_type_class_add_private (gobject_class, sizeof (GooCanvasTextPrivate)); + gobject_class->finalize = goo_canvas_text_model_finalize; gobject_class->get_property = goo_canvas_text_model_get_property; @@ -855,10 +947,14 @@ goo_canvas_text_model_class_init (GooCanvasTextModelClass *klass) static void goo_canvas_text_model_init (GooCanvasTextModel *tmodel) { + GooCanvasTextPrivate *priv = GOO_CANVAS_TEXT_MODEL_GET_PRIVATE (tmodel); + tmodel->text_data.width = -1.0; tmodel->text_data.anchor = GTK_ANCHOR_NW; tmodel->text_data.ellipsize = PANGO_ELLIPSIZE_NONE; tmodel->text_data.wrap = PANGO_WRAP_WORD; + + priv->height = -1.0; } @@ -952,9 +1048,10 @@ goo_canvas_text_model_get_property (GObject *object, GParamSpec *pspec) { GooCanvasTextModel *tmodel = (GooCanvasTextModel*) object; + GooCanvasTextPrivate *priv = GOO_CANVAS_TEXT_MODEL_GET_PRIVATE (tmodel); - goo_canvas_text_get_common_property (object, &tmodel->text_data, prop_id, - value, pspec); + goo_canvas_text_get_common_property (object, &tmodel->text_data, priv, + prop_id, value, pspec); } @@ -965,9 +1062,10 @@ goo_canvas_text_model_set_property (GObject *object, GParamSpec *pspec) { GooCanvasTextModel *tmodel = (GooCanvasTextModel*) object; + GooCanvasTextPrivate *priv = GOO_CANVAS_TEXT_MODEL_GET_PRIVATE (tmodel); - goo_canvas_text_set_common_property (object, &tmodel->text_data, prop_id, - value, pspec); + goo_canvas_text_set_common_property (object, &tmodel->text_data, priv, + prop_id, value, pspec); g_signal_emit_by_name (tmodel, "changed", TRUE); } diff --git a/src/goocanvas/src/goocanvasutils.c b/src/goocanvas/src/goocanvasutils.c index 3b14387..ca07559 100644 --- a/src/goocanvas/src/goocanvasutils.c +++ b/src/goocanvas/src/goocanvasutils.c @@ -366,7 +366,7 @@ goo_canvas_line_dash_get_type (void) if (cairo_line_dash_type == 0) cairo_line_dash_type = g_boxed_type_register_static - ("GooCairoLineDash", + ("GooCanvasLineDash", (GBoxedCopyFunc) goo_canvas_line_dash_ref, (GBoxedFreeFunc) goo_canvas_line_dash_unref); @@ -1192,3 +1192,103 @@ goo_canvas_bounds_get_type (void) } +/* Converts red, green, blue and alpha doubles to an RGBA guint. */ +guint +goo_canvas_convert_colors_to_rgba (double red, + double green, + double blue, + double alpha) +{ + guint red_byte, green_byte, blue_byte, alpha_byte; + + red_byte = red * 256; + red_byte -= red_byte >> 8; + + green_byte = green * 256; + green_byte -= green_byte >> 8; + + blue_byte = blue * 256; + blue_byte -= blue_byte >> 8; + + alpha_byte = alpha * 256; + alpha_byte -= alpha_byte >> 8; + + return (red_byte << 24) + (green_byte << 16) + (blue_byte << 8) + alpha_byte; +} + + +void +goo_canvas_get_rgba_value_from_pattern (cairo_pattern_t *pattern, + GValue *value) +{ + double red, green, blue, alpha; + guint rgba = 0; + + if (pattern && cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID) + { + cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha); + rgba = goo_canvas_convert_colors_to_rgba (red, green, blue, alpha); + } + g_value_set_uint (value, rgba); +} + + +/* Sets a style property to the given pattern, taking ownership of it. */ +void +goo_canvas_set_style_property_from_pattern (GooCanvasStyle *style, + GQuark property_id, + cairo_pattern_t *pattern) +{ + GValue tmpval = { 0 }; + + g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN); + g_value_take_boxed (&tmpval, pattern); + goo_canvas_style_set_property (style, property_id, &tmpval); + g_value_unset (&tmpval); +} + + +cairo_pattern_t* +goo_canvas_create_pattern_from_color_value (const GValue *value) +{ + GdkColor color = { 0, 0, 0, 0, }; + + if (g_value_get_string (value)) + gdk_color_parse (g_value_get_string (value), &color); + + return cairo_pattern_create_rgb (color.red / 65535.0, + color.green / 65535.0, + color.blue / 65535.0); +} + + +cairo_pattern_t* +goo_canvas_create_pattern_from_rgba_value (const GValue *value) +{ + guint rgba, red, green, blue, alpha; + + rgba = g_value_get_uint (value); + red = (rgba >> 24) & 0xFF; + green = (rgba >> 16) & 0xFF; + blue = (rgba >> 8) & 0xFF; + alpha = (rgba) & 0xFF; + + return cairo_pattern_create_rgba (red / 255.0, green / 255.0, + blue / 255.0, alpha / 255.0); +} + + +cairo_pattern_t* +goo_canvas_create_pattern_from_pixbuf_value (const GValue *value) +{ + GdkPixbuf *pixbuf; + cairo_surface_t *surface; + cairo_pattern_t *pattern; + + pixbuf = g_value_get_object (value); + surface = goo_canvas_cairo_surface_from_pixbuf (pixbuf); + pattern = cairo_pattern_create_for_surface (surface); + cairo_surface_destroy (surface); + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); + return pattern; +} diff --git a/src/goocanvas/src/goocanvasutils.h b/src/goocanvas/src/goocanvasutils.h index fa1ce93..7f158d4 100644 --- a/src/goocanvas/src/goocanvasutils.h +++ b/src/goocanvas/src/goocanvasutils.h @@ -86,7 +86,7 @@ typedef enum GOO_CANVAS_ITEM_HIDDEN = 0, GOO_CANVAS_ITEM_INVISIBLE = 1, GOO_CANVAS_ITEM_VISIBLE = 2, - GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD = 3, + GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD = 3 } GooCanvasItemVisibility; @@ -206,6 +206,92 @@ struct _GooCanvasLineDash double dash_offset; }; + +/* These are here so we can document the cairo type wrappers - don't use. */ +#if 0 +typedef cairo_antialias_t GooCairoAntialias; +typedef cairo_fill_rule_t GooCairoFillRule; +typedef cairo_hint_metrics_t GooCairoHintMetrics; +typedef cairo_line_cap_t GooCairoLineCap; +typedef cairo_line_join_t GooCairoLineJoin; +typedef cairo_operator_t GooCairoOperator; +typedef cairo_matrix_t GooCairoMatrix; +typedef cairo_pattern_t GooCairoPattern; +#endif + +/** + * GooCairoAntialias + * + * #GooCairoAntialias is simply a wrapper for the #cairo_antialias_t type, + * allowing it to be used for #GObject properties. + * + * See the #cairo_antialias_t documentation. + */ + +/** + * GooCairoFillRule + * + * #GooCairoFillRule is simply a wrapper for the #cairo_fill_rule_t type, + * allowing it to be used for #GObject properties. + * + * See the #cairo_fill_rule_t documentation. + */ + +/** + * GooCairoHintMetrics + * + * #GooCairoHintMetrics is simply a wrapper for the #cairo_hint_metrics_t type, + * allowing it to be used for #GObject properties. + * + * See the #cairo_hint_metrics_t documentation. + */ + +/** + * GooCairoLineCap + * + * #GooCairoLineCap is simply a wrapper for the #cairo_line_cap_t type, + * allowing it to be used for #GObject properties. + * + * See the #cairo_line_cap_t documentation. + */ + +/** + * GooCairoLineJoin + * + * #GooCairoLineJoin is simply a wrapper for the #cairo_line_join_t type, + * allowing it to be used for #GObject properties. + * + * See the #cairo_line_join_t documentation. + */ + +/** + * GooCairoOperator + * + * #GooCairoOperator is simply a wrapper for the #cairo_operator_t type, + * allowing it to be used for #GObject properties. + * + * See the #cairo_operator_t documentation. + */ + +/** + * GooCairoMatrix + * + * #GooCairoMatrix is simply a wrapper for the #cairo_matrix_t type, + * allowing it to be used for #GObject properties. + * + * See the #cairo_matrix_t documentation. + */ + +/** + * GooCairoPattern + * + * #GooCairoPattern is simply a wrapper for the #cairo_pattern_t type, + * allowing it to be used for #GObject properties. + * + * See the #cairo_pattern_t documentation. + */ + + #define GOO_TYPE_CANVAS_LINE_DASH (goo_canvas_line_dash_get_type ()) GType goo_canvas_line_dash_get_type (void) G_GNUC_CONST; GooCanvasLineDash* goo_canvas_line_dash_new (gint num_dashes, diff --git a/src/goocanvas/src/goocanvaswidget.c b/src/goocanvas/src/goocanvaswidget.c index 974892f..e8ddacc 100644 --- a/src/goocanvas/src/goocanvaswidget.c +++ b/src/goocanvas/src/goocanvaswidget.c @@ -12,6 +12,10 @@ * * GooCanvasWidget provides support for placing any GtkWidget in the canvas. * + * The #GooCanvasWidget:width and #GooCanvasWidget:height properties specify + * the widget's size. If either of them is -1, then the requested size of the + * widget is used instead, which is the default for both width and height. + * * Note that there are a number of limitations in the use of #GooCanvasWidget: * * @@ -26,6 +30,8 @@ * * It doesn't have a model/view variant like the other standard items, * so it can only be used in a simple canvas without a model. + * + * It can't be made a static item. * */ #include @@ -153,6 +159,73 @@ goo_canvas_widget_new (GooCanvasItem *parent, } +/* Returns the anchor position, within the given width. */ +static gdouble +goo_canvas_widget_anchor_horizontal_pos (GtkAnchorType anchor, + gdouble width) +{ + switch(anchor) + { + case GTK_ANCHOR_N: + case GTK_ANCHOR_CENTER: + case GTK_ANCHOR_S: + return width / 2.0; + case GTK_ANCHOR_NE: + case GTK_ANCHOR_E: + case GTK_ANCHOR_SE: + return width; + default: + return 0.0; + } +} + + +/* Returns the anchor position, within the given height. */ +static gdouble +goo_canvas_widget_anchor_vertical_pos (GtkAnchorType anchor, + gdouble height) +{ + switch (anchor) + { + case GTK_ANCHOR_W: + case GTK_ANCHOR_CENTER: + case GTK_ANCHOR_E: + return height / 2.0; + case GTK_ANCHOR_SW: + case GTK_ANCHOR_S: + case GTK_ANCHOR_SE: + return height; + default: + return 0.0; + } +} + + +/* Returns the size to use for the widget, either the item's width & height + properties or the widget's own requested width & height. */ +static void +goo_canvas_widget_get_widget_size (GooCanvasWidget *witem, + gdouble *width, + gdouble *height) +{ + GtkRequisition requisition; + + if (witem->widget) + { + /* Get the widget's requested size, if we need it. */ + if (witem->width < 0 || witem->height < 0) + gtk_widget_size_request (witem->widget, &requisition); + + *width = witem->width < 0 ? requisition.width : witem->width; + *height = witem->height < 0 ? requisition.height : witem->height; + } + else + { + *width = *height = 0.0; + } +} + + static void goo_canvas_widget_set_widget (GooCanvasWidget *witem, GtkWidget *widget) @@ -347,53 +420,19 @@ goo_canvas_widget_update (GooCanvasItemSimple *simple, cairo_t *cr) { GooCanvasWidget *witem = (GooCanvasWidget*) simple; - GtkRequisition requisition; gdouble width, height; if (witem->widget) { - /* Compute the new bounds. */ - if (witem->width < 0 || witem->height < 0) - { - gtk_widget_size_request (witem->widget, &requisition); - } + goo_canvas_widget_get_widget_size (witem, &width, &height); simple->bounds.x1 = witem->x; simple->bounds.y1 = witem->y; - width = witem->width < 0 ? requisition.width : witem->width; - height = witem->height < 0 ? requisition.height : witem->height; - - switch (witem->anchor) - { - case GTK_ANCHOR_N: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_S: - simple->bounds.x1 -= width / 2.0; - break; - case GTK_ANCHOR_NE: - case GTK_ANCHOR_E: - case GTK_ANCHOR_SE: - simple->bounds.x1 -= width; - break; - default: - break; - } - switch (witem->anchor) - { - case GTK_ANCHOR_W: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_E: - simple->bounds.y1 -= height / 2.0; - break; - case GTK_ANCHOR_SW: - case GTK_ANCHOR_S: - case GTK_ANCHOR_SE: - simple->bounds.y1 -= height; - break; - default: - break; - } + simple->bounds.x1 -= + goo_canvas_widget_anchor_horizontal_pos (witem->anchor, width); + simple->bounds.y1 -= + goo_canvas_widget_anchor_vertical_pos (witem->anchor, height); simple->bounds.x2 = simple->bounds.x1 + width; simple->bounds.y2 = simple->bounds.y1 + height; @@ -544,6 +583,7 @@ goo_canvas_widget_class_init (GooCanvasWidgetClass *klass) G_MAXDOUBLE, -1.0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_ANCHOR, g_param_spec_enum ("anchor", _("Anchor"), @@ -555,5 +595,3 @@ goo_canvas_widget_class_init (GooCanvasWidgetClass *klass) g_object_class_override_property (gobject_class, PROP_VISIBILITY, "visibility"); } - - -- cgit v0.9.1