def addPixelDataClass(module, pd, img, bpp, doc=""): # This function creates a ClassDef for a PixelData class defined in C++. # The C++ versions are template instantiations, so this allows us to # create nearly identical classes and just substitute the image class # name and the pixel data class name. #itrName = 'Iterator' itrName = pd + '_Accessor' module.addHeaderCode('typedef %s::Iterator %s;' % (pd, itrName)) # First generate the class and methods for the PixelData class cls = ClassDef(name=pd, bases=['wxPixelDataBase'], briefDoc=doc, items=[ MethodDef( name=pd, isCtor=True, items=[ParamDef(type=img + '&', name='bmp')], overloads=[ MethodDef(name=pd, isCtor=True, items=[ ParamDef(type=img + '&', name='bmp'), ParamDef(type='const wxRect&', name='rect') ]), MethodDef(name=pd, isCtor=True, items=[ ParamDef(type=img + '&', name='bmp'), ParamDef(type='const wxPoint&', name='pt'), ParamDef(type='const wxSize&', name='sz') ]), ]), MethodDef(name='~' + pd, isDtor=True), MethodDef(type=itrName, name='GetPixels', isConst=True), CppMethodDef('int', '__nonzero__', '()', body="""\ return (int)self->operator bool(); """), ]) # add this class to the module module.addItem(cls) # Now do the class and methods for its C++ Iterator class icls = ClassDef( name=itrName, items=[ # Constructors MethodDef(name=itrName, isCtor=True, items=[ParamDef(name='data', type=pd + '&')], overloads=[ MethodDef(name=itrName, isCtor=True, items=[ ParamDef(name='bmp', type=img + '&'), ParamDef(name='data', type=pd + '&') ]), MethodDef(name=itrName, isCtor=True) ]), MethodDef(name='~' + itrName, isDtor=True), # Methods MethodDef(type='void', name='Reset', items=[ParamDef(type='const %s&' % pd, name='data')]), MethodDef(type='bool', name='IsOk', isConst=True), CppMethodDef('int', '__nonzero__', '()', body="""\ return (int)self->IsOk(); """), MethodDef(type='void', name='Offset', items=[ ParamDef(type='const %s&' % pd, name='data'), ParamDef(type='int', name='x'), ParamDef(type='int', name='y') ]), MethodDef(type='void', name='OffsetX', items=[ ParamDef(type='const %s&' % pd, name='data'), ParamDef(type='int', name='x') ]), MethodDef(type='void', name='OffsetY', items=[ ParamDef(type='const %s&' % pd, name='data'), ParamDef(type='int', name='y') ]), MethodDef(type='void', name='MoveTo', items=[ ParamDef(type='const %s&' % pd, name='data'), ParamDef(type='int', name='x'), ParamDef(type='int', name='y') ]), # should this return the iterator? CppMethodDef('void', 'nextPixel', '()', body="++(*self);"), # NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha # functions because I can't hide the premultiplying needed on wxMSW # if only the individual components are wrapped, plus it would mean 3 # or 4 trips per pixel from Python to C++ instead of just one. # Instead I'll add the Set and Get functions below and put the # premultiplying in there. ]) assert bpp in [24, 32] if bpp == 24: icls.addCppMethod('void', 'Set', '(byte red, byte green, byte blue)', body="""\ self->Red() = red; self->Green() = green; self->Blue() = blue; """) icls.addCppMethod('PyObject*', 'Get', '()', body="""\ wxPyThreadBlocker blocker; PyObject* rv = PyTuple_New(3); PyTuple_SetItem(rv, 0, wxPyInt_FromLong(self->Red())); PyTuple_SetItem(rv, 1, wxPyInt_FromLong(self->Green())); PyTuple_SetItem(rv, 2, wxPyInt_FromLong(self->Blue())); return rv; """) elif bpp == 32: icls.addCppMethod('void', 'Set', '(byte red, byte green, byte blue, byte alpha)', body="""\ self->Red() = wxPy_premultiply(red, alpha); self->Green() = wxPy_premultiply(green, alpha); self->Blue() = wxPy_premultiply(blue, alpha); self->Alpha() = alpha; """) icls.addCppMethod('PyObject*', 'Get', '()', body="""\ wxPyThreadBlocker blocker; PyObject* rv = PyTuple_New(4); int red = self->Red(); int green = self->Green(); int blue = self->Blue(); int alpha = self->Alpha(); PyTuple_SetItem(rv, 0, wxPyInt_FromLong( wxPy_unpremultiply(red, alpha) )); PyTuple_SetItem(rv, 1, wxPyInt_FromLong( wxPy_unpremultiply(green, alpha) )); PyTuple_SetItem(rv, 2, wxPyInt_FromLong( wxPy_unpremultiply(blue, alpha) )); PyTuple_SetItem(rv, 3, wxPyInt_FromLong( alpha )); return rv; """) # add it to the main pixel data class as a nested class #cls.insertItem(0, icls) # It's really a nested class, but we're pretending that it isn't (see the # typedef above) so add it at the module level instead. module.addItem(icls)
def addPixelDataClass(module, pd, img, bpp, doc=""): # This function creates a ClassDef for a PixelData class defined in C++. # The C++ versions are template instantiations, so this allows us to # create nearly identical classes and just substitute the image class # name and the pixel data class name. #itrName = 'Iterator' itrName = pd + '_Accessor' module.addHeaderCode('typedef %s::Iterator %s;' % (pd, itrName)) # First generate the class and methods for the PixelData class cls = ClassDef(name=pd, bases=['wxPixelDataBase'], briefDoc=doc, items=[ MethodDef(name=pd, isCtor=True, items=[ ParamDef(type=img+'&', name='bmp')], overloads=[ MethodDef(name=pd, isCtor=True, items=[ ParamDef(type=img+'&', name='bmp'), ParamDef(type='const wxRect&', name='rect')]), MethodDef(name=pd, isCtor=True, items=[ ParamDef(type=img+'&', name='bmp'), ParamDef(type='const wxPoint&', name='pt' ), ParamDef(type='const wxSize&', name='sz' )]), ]), MethodDef(name='~'+pd, isDtor=True), MethodDef(type=itrName, name='GetPixels', isConst=True), CppMethodDef('int', '__nonzero__', '()', body="""\ return (int)self->operator bool(); """), ]) # add this class to the module module.addItem(cls) # Now do the class and methods for its C++ Iterator class icls = ClassDef(name=itrName, items=[ # Constructors MethodDef(name=itrName, isCtor=True, items=[ ParamDef(name='data', type=pd+'&')], overloads=[ MethodDef(name=itrName, isCtor=True, items=[ ParamDef(name='bmp', type=img+'&'), ParamDef(name='data', type=pd+'&')]), MethodDef(name=itrName, isCtor=True)]), MethodDef(name='~'+itrName, isDtor=True), # Methods MethodDef(type='void', name='Reset', items=[ ParamDef(type='const %s&' % pd, name='data')]), MethodDef(type='bool', name='IsOk', isConst=True), CppMethodDef('int', '__nonzero__', '()', body="""\ return (int)self->IsOk(); """), MethodDef(type='void', name='Offset', items=[ ParamDef(type='const %s&' % pd, name='data'), ParamDef(type='int', name='x'), ParamDef(type='int', name='y')]), MethodDef(type='void', name='OffsetX', items=[ ParamDef(type='const %s&' % pd, name='data'), ParamDef(type='int', name='x')]), MethodDef(type='void', name='OffsetY', items=[ ParamDef(type='const %s&' % pd, name='data'), ParamDef(type='int', name='y')]), MethodDef(type='void', name='MoveTo', items=[ ParamDef(type='const %s&' % pd, name='data'), ParamDef(type='int', name='x'), ParamDef(type='int', name='y')]), # should this return the iterator? CppMethodDef('void', 'nextPixel', '()', body="++(*self);"), # NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha # functions because I can't hide the premultiplying needed on wxMSW # if only the individual components are wrapped, plus it would mean 3 # or 4 trips per pixel from Python to C++ instead of just one. # Instead I'll add the Set and Get functions below and put the # premultiplying in there. ]) assert bpp in [24, 32] if bpp == 24: icls.addCppMethod('void', 'Set', '(byte red, byte green, byte blue)', body="""\ self->Red() = red; self->Green() = green; self->Blue() = blue; """) icls.addCppMethod('PyObject*', 'Get', '()', body="""\ wxPyThreadBlocker blocker; PyObject* rv = PyTuple_New(3); PyTuple_SetItem(rv, 0, wxPyInt_FromLong(self->Red())); PyTuple_SetItem(rv, 1, wxPyInt_FromLong(self->Green())); PyTuple_SetItem(rv, 2, wxPyInt_FromLong(self->Blue())); return rv; """) elif bpp == 32: icls.addCppMethod('void', 'Set', '(byte red, byte green, byte blue, byte alpha)', body="""\ self->Red() = wxPy_premultiply(red, alpha); self->Green() = wxPy_premultiply(green, alpha); self->Blue() = wxPy_premultiply(blue, alpha); self->Alpha() = alpha; """) icls.addCppMethod('PyObject*', 'Get', '()', body="""\ wxPyThreadBlocker blocker; PyObject* rv = PyTuple_New(4); int red = self->Red(); int green = self->Green(); int blue = self->Blue(); int alpha = self->Alpha(); PyTuple_SetItem(rv, 0, wxPyInt_FromLong( wxPy_unpremultiply(red, alpha) )); PyTuple_SetItem(rv, 1, wxPyInt_FromLong( wxPy_unpremultiply(green, alpha) )); PyTuple_SetItem(rv, 2, wxPyInt_FromLong( wxPy_unpremultiply(blue, alpha) )); PyTuple_SetItem(rv, 3, wxPyInt_FromLong( alpha )); return rv; """) # add it to the main pixel data class as a nested class #cls.insertItem(0, icls) # It's really a nested class, but we're pretending that it isn't (see the # typedef above) so add it at the module level instead. module.addItem(icls)
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('wxIdManager') assert isinstance(c, etgtools.ClassDef) # no tweaks needed for this class # wxWindowIDRef is not documented (and probably rightly so) but we're going # to use it from Python anyway to help with preallocating IDs in a way that # allows them to be reused and be also be protected from conflicts from # other auto allocated IDs. # First, add defintions of the existing C++ class and its elements klass = ClassDef( name='wxWindowIDRef', bases=[], briefDoc="""\ A wxWindowIDRef object wraps an ID value and marks it as being in-use until all references to that ID are gone. """, items=[ MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True, briefDoc='Default constructor', overloads=[ MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True, briefDoc='Create reference from an ID', items=[ParamDef(type='int', name='id')]), MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True, briefDoc='Copy an ID reference', items=[ ParamDef(type='const wxWindowIDRef&', name='idref') ]), ]), MethodDef(name='~wxWindowIDRef', className='wxWindowIDRef', isDtor=True), MethodDef(type='int', name='GetValue', briefDoc='Get the ID value'), ]) # Now tweak it a bit klass.addCppMethod( 'int', 'GetId', '()', doc= "Alias for GetValue allowing the IDRef to be passed as the source parameter to :meth:`wx.EvtHandler.Bind`.", body="""\ return self->GetValue(); """) klass.addCppMethod( 'int', '__int__', '()', doc= "Alias for GetValue allowing the IDRef to be passed as the WindowID parameter when creating widgets or etc.", body="""\ return self->GetValue(); """) klass.addPyMethod('__repr__', '(self)', 'return "WindowIDRef: {}".format(self.GetId())') # and finish it up by adding it to the module module.addItem(klass) # Now, let's add a new Python function to the global scope that reserves an # ID (or range) and returns a ref object for it. module.addPyFunction('NewIdRef', '(count=1)', doc="""\ Reserves a new Window ID (or range of WindowIDs) and returns a :class:`wx.WindowIDRef` object (or list of them) that will help manage the reservation of that ID. This function is intended to be a drop-in replacement of the old and deprecated :func:`wx.NewId` function, with the added benefit that the ID should never conflict with an in-use ID or other IDs generated by this function. """, body="""\ if count == 1: return WindowIDRef(IdManager.ReserveId()) else: start = IdManager.ReserveId(count) IDRefs = [] for id in range(start, start+count): IDRefs.append(WindowIDRef(id)) return IDRefs """) #----------------------------------------------------------------- tools.doCommonTweaks(module) tools.runGenerators(module)
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('wxIdManager') assert isinstance(c, etgtools.ClassDef) # no tweaks needed for this class # wxWindowIDRef is not documented (and probably rightly so) but we're going # to use it from Python anyway to help with preallocating IDs in a way that # allows them to be reused and be also be protected from conflicts from # other auto allocated IDs. # First, add defintions of the existing C++ class and its elements klass = ClassDef(name='wxWindowIDRef', bases = [], briefDoc="""\ A wxWindowIDRef object wraps an ID value and marks it as being in-use until all references to that ID are gone. """, items = [ MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True, briefDoc='Default constructor', overloads=[ MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True, briefDoc='Create reference from an ID', items=[ ParamDef(type='int', name='id') ]), MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True, briefDoc='Copy an ID reference', items=[ ParamDef(type='const wxWindowIDRef&', name='idref') ]), ]), MethodDef(name='~wxWindowIDRef', className='wxWindowIDRef', isDtor=True), MethodDef(type='int', name='GetValue', briefDoc='Get the ID value'), ]) # Now tweak it a bit klass.addCppMethod('int', 'GetId', '()', doc="Alias for GetValue allowing the IDRef to be passed as the source parameter to :meth:`wx.EvtHandler.Bind`.", body="""\ return self->GetValue(); """) klass.addCppMethod('int', '__int__', '()', doc="Alias for GetValue allowing the IDRef to be passed as the WindowID parameter when creating widgets or etc.", body="""\ return self->GetValue(); """) klass.addCppMethod('bool', '__eq__', '(wxWindowID id)', "return self->GetValue() == id;") klass.addCppMethod('bool', '__ne__', '(wxWindowID id)', "return self->GetValue() != id;") klass.addCppMethod('bool', '__lt__', '(wxWindowID id)', "return self->GetValue() < id;") klass.addCppMethod('bool', '__gt__', '(wxWindowID id)', "return self->GetValue() > id;") klass.addCppMethod('bool', '__le__', '(wxWindowID id)', "return self->GetValue() <= id;") klass.addCppMethod('bool', '__ge__', '(wxWindowID id)', "return self->GetValue() >= id;") klass.addPyMethod('__repr__', '(self)', 'return "WindowIDRef: {}".format(self.GetId())') klass.addPyMethod('__hash__', '(self)', 'return hash(self.GetValue())') # and finish it up by adding it to the module module.addItem(klass) # Now, let's add a new Python function to the global scope that reserves an # ID (or range) and returns a ref object for it. module.addPyFunction('NewIdRef', '(count=1)', doc="""\ Reserves a new Window ID (or range of WindowIDs) and returns a :class:`wx.WindowIDRef` object (or list of them) that will help manage the reservation of that ID. This function is intended to be a drop-in replacement of the old and deprecated :func:`wx.NewId` function, with the added benefit that the ID should never conflict with an in-use ID or other IDs generated by this function. """, body="""\ if count == 1: return WindowIDRef(IdManager.ReserveId()) else: start = IdManager.ReserveId(count) IDRefs = [] for id in range(start, start+count): IDRefs.append(WindowIDRef(id)) return IDRefs """) #----------------------------------------------------------------- tools.doCommonTweaks(module) tools.runGenerators(module)