diff options
author | Paul Pogonyshev <pogonyshev@gmx.net> | 2009-05-12 00:47:51 +0300 |
---|---|---|
committer | Paul Pogonyshev <pogonyshev@gmx.net> | 2009-05-15 22:49:56 +0300 |
commit | 15b7265a00d405d6115f45ba0b1f26019ef1a52b (patch) | |
tree | 647ba8393bd2279b63099171398a5d45a2e9bc51 /gtk/gdkcolor.override | |
parent | 029b2905baec78b370e76e1b2340dc2ee2ddaea1 (diff) | |
download | pygtk-15b7265a00d405d6115f45ba0b1f26019ef1a52b.tar.gz |
Add floating-point support to gtk.gdk.Color
Make constructor accept floating-point arguments. Add 'red_float',
'green_float' and 'blue_float' read-write properties. Test and
document new features. Part of bug #546019.
Diffstat (limited to 'gtk/gdkcolor.override')
-rw-r--r-- | gtk/gdkcolor.override | 220 |
1 files changed, 184 insertions, 36 deletions
diff --git a/gtk/gdkcolor.override b/gtk/gdkcolor.override index 3cb5329a..f46b8783 100644 --- a/gtk/gdkcolor.override +++ b/gtk/gdkcolor.override @@ -32,25 +32,19 @@ _wrap_gdk_color_new(PyGBoxed *self, { static char *kwlist1[] = {"red", "green", "blue", "pixel", NULL }; static char *kwlist2[] = { "spec", NULL }; - int red = 0, green = 0, blue = 0; - unsigned int pixel = 0; - const char *spec; + PyObject *red = Py_None, *green = Py_None, *blue = Py_None; + const char *spec = NULL; GdkColor colour; - if (PyArg_ParseTupleAndKeywords(args, kwargs, "|iiik:gdk.Color", kwlist1, - &red, &green, &blue, &pixel)) { - colour.red = red; - colour.green = green; - colour.blue = blue; - colour.pixel = pixel; - goto success; - } + /* Note: this constructor has become quite complicated, because it + * is heavily overloaded. Additionally, we try to optimize a + * little. */ - PyErr_Clear(); - - if (PyArg_ParseTupleAndKeywords(args, kwargs, "s:color_parse|gdk.Color", kwlist2, + if (PyArg_ParseTupleAndKeywords(args, kwargs, "|s:gdk.Color", kwlist2, &spec)) { - if (!gdk_color_parse(spec, &colour)) { + if (!spec) + memset(&colour, 0, sizeof(colour)); + else if (!gdk_color_parse(spec, &colour)) { PyErr_SetString(PyExc_ValueError, "unable to parse colour specification"); return -1; @@ -60,6 +54,77 @@ _wrap_gdk_color_new(PyGBoxed *self, } PyErr_Clear(); + + if (PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOk:gdk.Color", kwlist1, + &red, &green, &blue, &colour.pixel)) { + /* We don't allow mixing floats and non-floats as that is too + * error-prone. All non-floats are deemed integers in case + * they have __int__() method. */ + int have_floats = 0; + int have_nonfloats = 0; + + if (red == Py_None) + colour.red = 0; + else { + if (PyFloat_Check(red)) { + have_floats = 1; + colour.red = MIN(MAX(0.0, PyFloat_AsDouble(red)), 1.0) * 65535.0; + } + else { + have_nonfloats = 1; + colour.red = PyInt_AsLong(red); + } + } + + if (PyErr_Occurred()) + return -1; + + if (green == Py_None) + colour.green = 0; + else { + if (PyFloat_Check(green)) { + if (have_nonfloats) + goto mixed_types_error; + have_floats = 1; + colour.green = MIN(MAX(0.0, PyFloat_AsDouble(green)), 1.0) * 65535.0; + } + else { + if (have_floats) + goto mixed_types_error; + have_nonfloats = 1; + colour.green = PyInt_AsLong(green); + } + } + + if (PyErr_Occurred()) + return -1; + + if (blue == Py_None) + colour.blue = 0; + else { + if (PyFloat_Check(blue)) { + if (have_nonfloats) + goto mixed_types_error; + colour.blue = MIN(MAX(0.0, PyFloat_AsDouble(blue)), 1.0) * 65535.0; + } + else { + if (have_floats) + goto mixed_types_error; + colour.blue = PyInt_AsLong(blue); + } + } + + if (PyErr_Occurred()) + return -1; + + goto success; + + mixed_types_error: + PyErr_SetString(PyExc_TypeError, "arguments must either be all integers or all floats"); + return -1; + } + + PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "Usage:\n" " gtk.gdk.Color(red, green, blue, pixel) [all are optional]\n" " gtk.gdk.Color(spec) [see gtk.gdk.color_parse()]"); @@ -72,35 +137,118 @@ _wrap_gdk_color_new(PyGBoxed *self, return 0; } + %% -override-slot GdkColor.tp_setattr +override-attr GdkColor.red static int -_wrap_gdk_color_tp_setattr(PyGBoxed *self, char *attr, PyObject *value) +_wrap_gdk_color__set_red(PyObject *self, PyObject *value, void *closure) { - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "can't delete attributes"); + long red = PyInt_AsLong(value); + if (red == -1 && PyErr_Occurred()) return -1; + else { + pyg_boxed_get(self, GdkColor)->red = red; + return 0; } +} +%% +override-attr GdkColor.blue +static int +_wrap_gdk_color__set_blue(PyObject *self, PyObject *value, void *closure) +{ + long blue = PyInt_AsLong(value); + if (blue == -1 && PyErr_Occurred()) + return -1; + else { + pyg_boxed_get(self, GdkColor)->blue = blue; + return 0; + } +} +%% +override-attr GdkColor.green +static int +_wrap_gdk_color__set_green(PyObject *self, PyObject *value, void *closure) +{ + long green = PyInt_AsLong(value); + if (green == -1 && PyErr_Occurred()) + return -1; + else { + pyg_boxed_get(self, GdkColor)->green = green; + return 0; + } +} +%% +override-attr GdkColor.pixel +static int +_wrap_gdk_color__set_pixel(PyObject *self, PyObject *value, void *closure) +{ + long pixel = PyInt_AsLong(value); + if (pixel == -1 && PyErr_Occurred()) + return -1; + else { + pyg_boxed_get(self, GdkColor)->pixel = pixel; + return 0; + } +} +%% +override-attr GdkColor.red_float - if (PyInt_Check(value)) { - int i = PyInt_AsLong(value); - if (!strcmp(attr, "red")) { - pyg_boxed_get(self, GdkColor)->red = i; - return 0; - } else if (!strcmp(attr, "green")) { - pyg_boxed_get(self, GdkColor)->green = i; - return 0; - } else if (!strcmp(attr, "blue")) { - pyg_boxed_get(self, GdkColor)->blue = i; - return 0; - } else if (!strcmp(attr, "pixel")) { - pyg_boxed_get(self, GdkColor)->pixel = i; - return 0; - } +static PyObject * +_wrap_gdk_color__get_red_float(PyObject *self, void *closure) +{ + return PyFloat_FromDouble(pyg_boxed_get(self, GdkColor)->red / 65535.0); +} + +static int +_wrap_gdk_color__set_red_float(PyObject *self, PyObject *value, void *closure) +{ + double red = PyFloat_AsDouble(value); + if (red == -1 && PyErr_Occurred()) + return -1; + else { + pyg_boxed_get(self, GdkColor)->red = MIN(MAX(0.0, red), 1.0) * 65535.0; + return 0; } +} +%% +override-attr GdkColor.green_float - PyErr_SetString(PyExc_AttributeError, "could not write attribute"); - return -1; +static PyObject * +_wrap_gdk_color__get_green_float(PyObject *self, void *closure) +{ + return PyFloat_FromDouble(pyg_boxed_get(self, GdkColor)->green / 65535.0); +} + +static int +_wrap_gdk_color__set_green_float(PyObject *self, PyObject *value, void *closure) +{ + double green = PyFloat_AsDouble(value); + if (green == -1 && PyErr_Occurred()) + return -1; + else { + pyg_boxed_get(self, GdkColor)->green = MIN(MAX(0.0, green), 1.0) * 65535.0; + return 0; + } +} +%% +override-attr GdkColor.blue_float + +static PyObject * +_wrap_gdk_color__get_blue_float(PyObject *self, void *closure) +{ + return PyFloat_FromDouble(pyg_boxed_get(self, GdkColor)->blue / 65535.0); +} + +static int +_wrap_gdk_color__set_blue_float(PyObject *self, PyObject *value, void *closure) +{ + double blue = PyFloat_AsDouble(value); + if (blue == -1 && PyErr_Occurred()) + return -1; + else { + pyg_boxed_get(self, GdkColor)->blue = MIN(MAX(0.0, blue), 1.0) * 65535.0; + return 0; + } } %% override gdk_color_parse kwargs |