1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
#---------------------------------------------------------------------------
# Name: etg/palette.py
# Author: Scott Talbert
#
# Created: 31-Jul-2016
# Copyright: (c) 2016-2020 by Total Control Software
# License: wxWindows License
#---------------------------------------------------------------------------
import etgtools
import etgtools.tweaker_tools as tools
from textwrap import dedent
PACKAGE = "wx"
MODULE = "_core"
NAME = "palette" # Base name of the file to generate to for this script
DOCSTRING = ""
# The classes and/or the basename of the Doxygen XML files to be processed by
# this script.
ITEMS = [ 'wxPalette' ]
#---------------------------------------------------------------------------
def run():
# Parse the XML file(s) building a collection of Extractor objects
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
etgtools.parseDoxyXML(module, ITEMS)
#-----------------------------------------------------------------
# Tweak the parsed meta objects in the module object as needed for
# customizing the generated code and docstrings.
c = module.find('wxPalette')
tools.removeVirtuals(c)
# Add a helper function for use with the Create method and the Ctor
# accepting RGB data.
c.addCppCode("""\
// a helper function to be used in the Create method and one of the Ctors
bool _paletteCreateHelper(wxPalette* self,
PyObject* red, PyObject* green, PyObject* blue) {
bool rval = false;
wxPyThreadBlocker blocker;
char* errMsg = "Expected a sequence of integer objects";
if (!PySequence_Check(red) || !PySequence_Check(green) || !PySequence_Check(blue)) {
PyErr_SetString(PyExc_TypeError, errMsg);
return rval;
}
Py_ssize_t count = PySequence_Size(red);
if (PySequence_Size(green) != count || PySequence_Size(blue) != count) {
PyErr_SetString(PyExc_ValueError, "Sequence lengths must be equal");
return rval;
}
unsigned char* redArray = new unsigned char[count];
unsigned char* greenArray = new unsigned char[count];
unsigned char* blueArray = new unsigned char[count];
for (Py_ssize_t i = 0; i < count; i++) {
PyObject* redItem = PySequence_ITEM(red, i);
PyObject* greenItem = PySequence_ITEM(green, i);
PyObject* blueItem = PySequence_ITEM(blue, i);
if (!wxPyInt_Check(redItem) || !wxPyInt_Check(greenItem) || !wxPyInt_Check(blueItem)) {
PyErr_SetString(PyExc_TypeError, errMsg);
goto pch_exit;
}
long redLong = wxPyInt_AsLong(redItem);
long greenLong = wxPyInt_AsLong(greenItem);
long blueLong = wxPyInt_AsLong(blueItem);
Py_DECREF(redItem);
Py_DECREF(greenItem);
Py_DECREF(blueItem);
if (redLong < 0 || redLong > 255 || greenLong < 0 || greenLong > 255 || blueLong < 0 || blueLong > 255) {
PyErr_SetString(PyExc_ValueError, "Sequence values must be in the 0..255 range");
goto pch_exit;
}
redArray[i] = redLong;
greenArray[i] = greenLong;
blueArray[i] = blueLong;
}
rval = self->Create(count, redArray, greenArray, blueArray);
pch_exit:
delete[] redArray;
delete[] greenArray;
delete[] blueArray;
return rval;
}
""")
#-----------------------------------------------------------------
# Replace the constructor accepting the arrays of RGB values with one that
# understands any Python sequence.
c.find('wxPalette').findOverload('red').ignore()
c.addCppCtor('(PyObject* red, PyObject* green, PyObject* blue)',
doc=dedent("""\
Creates a palette from a set of sequences of integers,
one for each red, green and blue color components.
:param red: A sequence of integer values in the range 0..255 inclusive.
:param green: A sequence of integer values in the range 0..255 inclusive.
:param blue: A sequence of integer values in the range 0..255 inclusive.
.. note:: All sequences must be the same length.
"""),
body="""\
wxPalette* pal = new wxPalette;
_paletteCreateHelper(pal, red, green, blue);
if (PyErr_Occurred()) {
delete pal;
return NULL;
}
return pal;
""")
c.find('GetPixel.red').pyInt = True
c.find('GetPixel.green').pyInt = True
c.find('GetPixel.blue').pyInt = True
c.find('GetRGB').ignore()
c.addCppMethod('PyObject*', 'GetRGB', '(int pixel)',
pyArgsString="(pixel) -> (red, green, blue)",
doc="Returns RGB values for a given palette index.",
body="""\
unsigned char red;
unsigned char green;
unsigned char blue;
wxPyThreadBlocker blocker;
if (!self->GetRGB(pixel, &red, &green, &blue)) {
PyErr_SetString(PyExc_IndexError, "Pixel out of range");
return NULL;
}
PyObject* rv = PyTuple_New(3);
PyTuple_SetItem(rv, 0, wxPyInt_FromLong(red));
PyTuple_SetItem(rv, 1, wxPyInt_FromLong(green));
PyTuple_SetItem(rv, 2, wxPyInt_FromLong(blue));
return rv;
""")
# Replace the Create method with one that understands any kind of Python sequence
c.find('Create').ignore()
c.addCppMethod('PyObject*', 'Create', '(PyObject* red, PyObject* green, PyObject* blue)',
pyArgsString="(red, green, blue) -> bool",
doc=dedent("""\
Creates a palette from 3 sequences of integers, one for each red, blue or green component.
:param red: A sequence of integer values in the range 0..255 inclusive.
:param green: A sequence of integer values in the range 0..255 inclusive.
:param blue: A sequence of integer values in the range 0..255 inclusive.
.. note:: All sequences must be the same length.
"""),
body="""\
bool rval = _paletteCreateHelper(self, red, green, blue);
wxPyThreadBlocker blocker;
if (PyErr_Occurred())
return NULL;
if (rval)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
""")
#-----------------------------------------------------------------
tools.doCommonTweaks(module)
tools.runGenerators(module)
#---------------------------------------------------------------------------
if __name__ == '__main__':
run()
|