pygimp: adds proper support for layer groups

Layer groups where barely supported using numeric IDs and
by calling gimp.Item.from_id. This adds a Python
GroupLayer class.
parent 445b467e
......@@ -1770,6 +1770,8 @@ static struct _PyGimp_Functions pygimp_api_functions = {
pygimp_drawable_new,
&PyGimpLayer_Type,
pygimp_layer_new,
&PyGimpGroupLayer_Type,
pygimp_group_layer_new,
&PyGimpChannel_Type,
pygimp_channel_new,
&PyGimpVectors_Type,
......@@ -1820,6 +1822,12 @@ initgimp(void)
if (PyType_Ready(&PyGimpLayer_Type) < 0)
return;
PyGimpGroupLayer_Type.ob_type = &PyType_Type;
PyGimpGroupLayer_Type.tp_alloc = PyType_GenericAlloc;
PyGimpGroupLayer_Type.tp_new = PyType_GenericNew;
if (PyType_Ready(&PyGimpGroupLayer_Type) < 0)
return;
PyGimpChannel_Type.ob_type = &PyType_Type;
PyGimpChannel_Type.tp_alloc = PyType_GenericAlloc;
PyGimpChannel_Type.tp_new = PyType_GenericNew;
......@@ -1901,6 +1909,9 @@ initgimp(void)
Py_INCREF(&PyGimpLayer_Type);
PyModule_AddObject(m, "Layer", (PyObject *)&PyGimpLayer_Type);
Py_INCREF(&PyGimpGroupLayer_Type);
PyModule_AddObject(m, "GroupLayer", (PyObject *)&PyGimpGroupLayer_Type);
Py_INCREF(&PyGimpChannel_Type);
PyModule_AddObject(m, "Channel", (PyObject *)&PyGimpChannel_Type);
......
......@@ -37,7 +37,7 @@ typedef struct {
PyObject_HEAD
gint32 ID;
GimpDrawable *drawable;
} PyGimpDrawable, PyGimpLayer, PyGimpChannel;
} PyGimpDrawable, PyGimpLayer, PyGimpGroupLayer, PyGimpChannel;
typedef struct {
PyObject_HEAD
......@@ -60,6 +60,9 @@ struct _PyGimp_Functions {
PyTypeObject *Layer_Type;
PyObject *(* layer_new)(gint32 ID);
PyTypeObject *GroupLayer_Type;
PyObject *(* group_layer_new)(gint32 ID);
PyTypeObject *Channel_Type;
PyObject *(* channel_new)(gint32 ID);
......@@ -87,6 +90,8 @@ struct _PyGimp_Functions *_PyGimp_API;
#define pygimp_drawable_new (_PyGimp_API->drawable_new)
#define PyGimpLayer_Type (_PyGimp_API->Layer_Type)
#define pygimp_layer_new (_PyGimp_API->layer_new)
#define PyGimpGroupLayer_Type (_PyGimp_API->GroupLayer_Type)
#define pygimp_group_layer_new (_PyGimp_API->group_layer_new)
#define PyGimpChannel_Type (_PyGimp_API->Channel_Type)
#define pygimp_channel_new (_PyGimp_API->channel_new)
#define PyGimpVectors_Type (_PyGimp_API->Vectors_Type)
......
......@@ -1923,6 +1923,118 @@ pygimp_layer_new(gint32 ID)
/* End of code for Layer objects */
/* -------------------------------------------------------- */
static PyMethodDef grouplay_methods[] = {
{NULL, NULL} /* sentinel */
};
static PyObject *
grouplay_get_layers(PyGimpGroupLayer *self, void *closure)
{
gint32 *layers;
gint n_layers, i;
PyObject *ret;
layers = gimp_item_get_children(self->ID, &n_layers);
ret = PyList_New(n_layers);
for (i = 0; i < n_layers; i++)
PyList_SetItem(ret, i, pygimp_group_layer_new(layers[i]));
g_free(layers);
return ret;
}
static PyGetSetDef grouplay_getsets[] = {
{ "layers", (getter)grouplay_get_layers, (setter)0 },
{ NULL, (getter)0, (setter)0 }
};
static PyObject *
grouplay_repr(PyGimpLayer *self)
{
PyObject *s;
gchar *name;
name = gimp_item_get_name(self->ID);
s = PyString_FromFormat("<gimp.GroupLayer '%s'>", name ? name : "(null)");
g_free(name);
return s;
}
PyTypeObject PyGimpGroupLayer_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"gimp.GroupLayer", /* tp_name */
sizeof(PyGimpGroupLayer), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)drw_dealloc, /* tp_dealloc */
(printfunc)0, /* tp_print */
(getattrfunc)0, /* tp_getattr */
(setattrfunc)0, /* tp_setattr */
(cmpfunc)drw_cmp, /* tp_compare */
(reprfunc)grouplay_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)0, /* tp_hash */
(ternaryfunc)0, /* tp_call */
(reprfunc)0, /* tp_str */
(getattrofunc)0, /* tp_getattro */
(setattrofunc)0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
NULL, /* Documentation string */
(traverseproc)0, /* tp_traverse */
(inquiry)0, /* tp_clear */
(richcmpfunc)0, /* tp_richcompare */
0, /* tp_weaklistoffset */
(getiterfunc)0, /* tp_iter */
(iternextfunc)0, /* tp_iternext */
grouplay_methods, /* tp_methods */
0, /* tp_members */
grouplay_getsets, /* tp_getset */
&PyGimpLayer_Type, /* tp_base */
(PyObject *)0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)lay_init, /* tp_init */
(allocfunc)0, /* tp_alloc */
(newfunc)0, /* tp_new */
};
PyObject *
pygimp_group_layer_new(gint32 ID)
{
PyGimpGroupLayer *self;
if (!gimp_item_is_valid(ID) || !gimp_item_is_layer(ID)) {
Py_INCREF(Py_None);
return Py_None;
}
if (!gimp_item_is_group(ID)) {
return pygimp_layer_new(ID);
}
self = PyObject_NEW(PyGimpGroupLayer, &PyGimpGroupLayer_Type);
if (self == NULL)
return NULL;
self->ID = ID;
self->drawable = NULL;
return (PyObject *)self;
}
/* End of code for GroupLayer objects */
/* -------------------------------------------------------- */
static PyObject *
chn_copy(PyGimpChannel *self)
......
......@@ -204,7 +204,7 @@ img_new_layer(PyGimpImage *self, PyObject *args, PyObject *kwargs)
return NULL;
}
return pygimp_layer_new(layer_id);
return pygimp_group_layer_new(layer_id);
}
......@@ -236,7 +236,7 @@ img_enable_undo(PyGimpImage *self)
static PyObject *
img_flatten(PyGimpImage *self)
{
return pygimp_layer_new(gimp_image_flatten(self->ID));
return pygimp_group_layer_new(gimp_image_flatten(self->ID));
}
static PyObject *
......@@ -316,7 +316,7 @@ img_merge_visible_layers(PyGimpImage *self, PyObject *args)
return NULL;
}
return pygimp_layer_new(id);
return pygimp_group_layer_new(id);
}
static PyObject *
......@@ -340,7 +340,7 @@ img_merge_down(PyGimpImage *self, PyObject *args)
return NULL;
}
return pygimp_layer_new(id);
return pygimp_group_layer_new(id);
}
static PyObject *
......@@ -359,7 +359,7 @@ img_pick_correlate_layer(PyGimpImage *self, PyObject *args)
return Py_None;
}
return pygimp_layer_new(id);
return pygimp_group_layer_new(id);
}
static PyObject *
......@@ -756,7 +756,7 @@ img_get_layer_by_tattoo(PyGimpImage *self, PyObject *args)
if (!PyArg_ParseTuple(args, "i:get_layer_by_tattoo", &tattoo))
return NULL;
return pygimp_layer_new(gimp_image_get_layer_by_tattoo(self->ID, tattoo));
return pygimp_group_layer_new(gimp_image_get_layer_by_tattoo(self->ID, tattoo));
}
static PyObject *
......@@ -1019,7 +1019,7 @@ img_get_active_layer(PyGimpImage *self, void *closure)
return Py_None;
}
return pygimp_layer_new(id);
return pygimp_group_layer_new(id);
}
static int
......@@ -1222,7 +1222,7 @@ img_get_layers(PyGimpImage *self, void *closure)
ret = PyList_New(n_layers);
for (i = 0; i < n_layers; i++)
PyList_SetItem(ret, i, pygimp_layer_new(layers[i]));
PyList_SetItem(ret, i, pygimp_group_layer_new(layers[i]));
g_free(layers);
......
......@@ -76,6 +76,10 @@ extern PyTypeObject PyGimpLayer_Type;
#define pygimp_layer_check(v) (PyObject_TypeCheck(v, &PyGimpLayer_Type))
PyObject *pygimp_layer_new(gint32 ID);
extern PyTypeObject PyGimpGroupLayer_Type;
#define pygimp_layer__group_check(v) (PyObject_TypeCheck(v, &PyGimpGroupLayer_Type))
PyObject *pygimp_group_layer_new(gint32 ID);
extern PyTypeObject PyGimpChannel_Type;
#define pygimp_channel_check(v) (PyObject_TypeCheck(v, &PyGimpChannel_Type))
PyObject *pygimp_channel_new(gint32 ID);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment