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('wxStaticBox') assert isinstance(c, etgtools.ClassDef) c.find('wxStaticBox.label').default = 'wxEmptyString' c.find('Create.label').default = 'wxEmptyString' tools.fixWindowClass(c) # TODO: The window-label ctor is only available on MSW and GTK so disable # for now. Maybe replace it with a factory function that returns None on # OSX?? c.find('wxStaticBox').findOverload('wxWindow *label').ignore() c.find('Create').findOverload('wxWindow *label').ignore() # "unfix" the 2nd ctor and Create method so the required parameter lists # are different enough for them to be overloaded. #for name in ['wxStaticBox', 'Create']: # m = c.find(name).findOverload('wxWindow *label') # m.find('id').default = '' # This is intentionally not documented, but I think it would be handy to # use from wxPython. meth = MethodDef( name='GetBordersForSizer', isConst=True, isVirtual=True, type='void', protection='public', briefDoc= "Returns extra space that may be needed for borders within a StaticBox.", items=[ ParamDef(name='borderTop', type='int*', out=True), ParamDef(name='borderOther', type='int*', out=True), ]) c.addItem(meth) module.addGlobalStr('wxStaticBoxNameStr', c) #----------------------------------------------------------------- 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('wxHtmlCell') assert isinstance(c, etgtools.ClassDef) c.addPrivateCopyCtor() c.find('SetNext.cell').transfer = True c.find('AdjustPagebreak.pagebreak').inOut = True m = c.find('Find') assert isinstance(m, etgtools.MethodDef) m.find('param').type = 'const char*' m.cppSignature = 'const wxHtmlCell* (int condition, const void* param)' m = MethodDef(name='GetAbsPos', type='wxPoint', isConst=True, items=[ParamDef(type='wxHtmlCell*', name='rootCell', default='NULL')], doc="""\ Returns absolute position of the cell on HTML canvas.\n If rootCell is provided, then it's considered to be the root of the hierarchy and the returned value is relative to it. """) c.addItem(m) m = MethodDef(name='GetRootCell', type='wxHtmlCell*', isConst=True, doc="Returns the root cell of the hierarchy.") c.addItem(m) c = module.find('wxHtmlContainerCell') c.find('InsertCell.cell').transfer = True fixCellClass(c) c = module.find('wxHtmlColourCell') fixCellClass(c) c = module.find('wxHtmlWidgetCell') fixCellClass(c) c = module.find('wxHtmlWordCell') fixCellClass(c) c = module.find('wxHtmlWordWithTabsCell') fixCellClass(c) c = module.find('wxHtmlFontCell') fixCellClass(c) #----------------------------------------------------------------- tools.doCommonTweaks(module) tools.runGenerators(module)
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. scrolled = module.find('wxScrolled') assert isinstance(scrolled, etgtools.ClassDef) scrolled.find('GetViewStart').findOverload('()').ignore() scrolled.find('GetViewStart.x').out = True scrolled.find('GetViewStart.y').out = True m = scrolled.find('CalcScrolledPosition').findOverload('xx') m.find('xx').out = True m.find('yy').out = True m = scrolled.find('CalcUnscrolledPosition').findOverload('xx') m.find('xx').out = True m.find('yy').out = True scrolled.find('GetScrollPixelsPerUnit.xUnit').out = True scrolled.find('GetScrollPixelsPerUnit.yUnit').out = True # Just ignore this one and let the already tweaked versions be inherited from wx.Window. scrolled.find('GetVirtualSize').ignore() scrolled.addPrivateCopyCtor() scrolled.addPrivateAssignOp() tools.fixWindowClass(scrolled) # Add back some virtuals that were removed in fixWindowClass scrolled.find('OnDraw').isVirtual = True scrolled.find('GetSizeAvailableForScrollTarget').isVirtual = True scrolled.find('GetSizeAvailableForScrollTarget').ignore(False) scrolled.find('SendAutoScrollEvents').isVirtual = True # The wxScrolledCanvas typedef will be output normally and SIP will treat # it like a class that has a wxScrolled mix-in as one of the base classes. # Let's add some more info to them for the doc generators. docBase = """\ The :ref:`{name}` class is a combination of the :ref:`{base}` and :ref:`Scrolled` classes, and manages scrolling for its client area, transforming the coordinates according to the scrollbar positions, and setting the scroll positions, thumb sizes and ranges according to the area in view. """ item = module.find('wxScrolledCanvas') item.docAsClass = True item.bases = ['wxWindow', 'wxScrolled'] item.briefDoc = docBase.format(name='ScrolledCanvas', base='Window') item.detailedDoc[0] = "This scrolled window is not intended to have children "\ "so it doesn't have special handling for TAB traversal "\ "or focus management." # move it ahead of wxScrolledWindow sw = module.find('wxScrolledWindow') module.items.remove(item) module.insertItemBefore(sw, item) # wxScrolledWindow is documented as a typedef but it's actually a class. # So we need to implement it that way here too in order to keep # static_casts and such happy. assert isinstance(sw, TypedefDef) # First, let's add a typedef to serve as the base class of # wxScrolledWindow, since SIP doesn't yet understand using template # instantiations as base classes. Setting noTypeName tells SIP to not use # the typedef name in the actual generated code, but the typedef's type # instead. td = TypedefDef(name='_ScrolledWindowBase', type='wxScrolled<wxPanel>', noTypeName=True, piIgnored=True) module.insertItemAfter(sw, td) module.addHeaderCode('typedef wxScrolled<wxPanel> _ScrolledWindowBase;') sw.ignore() # Now implement the class definition klass = ClassDef( name='wxScrolledWindow', bases=['_ScrolledWindowBase'], piBases=['Window', 'Scrolled'], briefDoc=sw.briefDoc, detailedDoc=sw.detailedDoc, items=[ MethodDef(name='wxScrolledWindow', isCtor=True, items=[], overloads=[ MethodDef(name='wxScrolledWindow', isCtor=True, items=[ ParamDef(name='parent', type='wxWindow*'), ParamDef(name='id', type='wxWindowID', default='wxID_ANY'), ParamDef(name='pos', type='const wxPoint&', default='wxDefaultPosition'), ParamDef(name='size', type='const wxSize&', default='wxDefaultSize'), ParamDef( name='style', type='long', default='wxScrolledWindowStyle'), ParamDef(name='name', type='const wxString&', default='wxPanelNameStr'), ]), ]), MethodDef(name='SetFocusIgnoringChildren', type='void', items=[], briefDoc="""\ In contrast to SetFocus() this will set the focus to the panel even if there are child windows in the panel. This is only rarely needed.""" ), ], ) tools.fixWindowClass(klass) module.insertItemAfter(td, klass) module.addPyCode( "PyScrolledWindow = wx.deprecated(ScrolledWindow, 'Use ScrolledWindow instead.')" ) #----------------------------------------------------------------- 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.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('wxVisualAttributes') assert isinstance(c, etgtools.ClassDef) # Mark the stucture memebers as read-only, and make copies of the values # when fetching them. This is to protect against cases where the # VisualAttributes object is transient and may be GC'd while we still are # using a reference to a C++ member value. c.find('colBg').noSetter = True c.find('colBg').getCode = """\ wxColour* clr = new wxColour(sipCpp->colBg); sipPy = wxPyConstructObject((void*)clr, "wxColour", true); """ c.find('colFg').noSetter = True c.find('colFg').getCode = """\ wxColour* clr = new wxColour(sipCpp->colFg); sipPy = wxPyConstructObject((void*)clr, "wxColour", true); """ c.find('font').noSetter = True c.find('font').getCode = """\ wxFont* font = new wxFont(sipCpp->font); sipPy = wxPyConstructObject((void*)font, "wxFont", true); """ c = module.find('wxWindow') assert isinstance(c, etgtools.ClassDef) module.addGlobalStr('wxPanelNameStr', c) c.find('FindFocus').mustHaveApp() c.find('GetCapture').mustHaveApp() # First we need to let the wrapper generator know about wxWindowBase since # AddChild and RemoveChild need to use that type in order to be virtualized. winbase = ClassDef( name='wxWindowBase', bases=['wxEvtHandler'], abstract=True, items=[ MethodDef(name='AddChild', isVirtual=True, type='void', protection='public', items=[ParamDef(name='child', type='wxWindowBase*')]), MethodDef(name='RemoveChild', isVirtual=True, type='void', protection='public', items=[ParamDef(name='child', type='wxWindowBase*')]) ]) module.insertItemBefore(c, winbase) # Now change the base class of wxWindow c.bases = ['wxWindowBase'] # And fix the arg types we get from Doxy c.find('AddChild.child').type = 'wxWindowBase*' c.find('RemoveChild.child').type = 'wxWindowBase*' # We now return you to our regularly scheduled programming... c.includeCppCode('src/window_ex.cpp') # ignore some overloads that will be ambiguous after wrapping c.find('GetChildren').overloads = [] c.find('GetChildren').noCopy = True for name in ['GetVirtualSize', 'GetPosition', 'GetScreenPosition']: c.find(name).findOverload('int *').ignore() # Fix ClientToScreen/ScreenToClient int * overloads for name in ['ClientToScreen', 'ScreenToClient']: c.find(name).findOverload('int *').find('x').inOut = True c.find(name).findOverload('int *').find('y').inOut = True # Like the above, but these also need to transplant the docs from the # ignored item to the non-ignored overload. for name in ['GetClientSize', 'GetSize']: c.find(name).findOverload('int *').ignore() item = c.find(name) ov = item.overloads[0] item.briefDoc = ov.briefDoc item.detailedDoc = ov.detailedDoc # Release the GIL for potentially blocking or long-running functions c.find('PopupMenu').releaseGIL() c.find('ProcessEvent').releaseGIL() c.find('ProcessWindowEvent').releaseGIL() c.find('ProcessWindowEventLocally').releaseGIL() # Add a couple wrapper functions for symmetry with the getters of the same name c.addPyMethod('SetRect', '(self, rect)', 'return self.SetSize(rect)') c.addPyProperty('Rect GetRect SetRect') c.addPyMethod('SetClientRect', '(self, rect)', 'return self.SetClientSize(rect)') c.addPyProperty('ClientRect GetClientRect SetClientRect') # Split the overloaded GetTextExtent into two distinct methods, because the # resulting method signatures are not different enough from the Python # perspective. m1 = c.find('GetTextExtent') #.findOverload('int *') assert len(m1.overloads) == 1 m2 = m1.overloads.pop() c.insertItemAfter(m1, m2) # Now do the needed tweaks for the full GetFullTextExtent m1.pyName = 'GetFullTextExtent' m1.find('w').out = True m1.find('h').out = True m1.find('descent').out = True m1.find('externalLeading').out = True c.find('GetHandle').type = 'wxUIntPtr*' c.find('GetHandle').setCppCode( "return new wxUIntPtr(wxPyGetWinHandle(self));") c.addCppMethod( 'void*', 'GetGtkWidget', '()', """\ #ifdef __WXGTK__ return (void*)self->GetHandle(); #else return NULL; #endif """) c.addCppMethod('void', 'AssociateHandle', '(long handle)', doc="Associate the window with a new native handle", body="self->AssociateHandle((WXWidget)handle);") c.addCppMethod('void', 'DissociateHandle', '()', doc="Dissociate the current native handle from the window", body="self->DissociateHandle();") # Add some new methods c.addCppMethod( 'wxWindow*', 'GetTopLevelParent', '()', 'return wxGetTopLevelParent(self);', briefDoc= "Returns the first ancestor of this window which is a top-level window." ) c.addCppMethod( 'bool', 'MacIsWindowScrollbar', '(const wxWindow* sb)', """\ #ifdef __WXMAC__ return self->MacIsWindowScrollbar(sb); #else return false; #endif """, pyArgsString="(sb)", briefDoc= "Is the given widget one of this window's built-in scrollbars? Only applicable on Mac." ) c.addCppMethod( 'void', 'SetDimensions', '(int x, int y, int width, int height, int sizeFlags=wxSIZE_AUTO)', pyArgsString="(x, y, width, height, sizeFlags=SIZE_AUTO)", body="""\ self->SetSize(x, y, width, height, sizeFlags); """) c.addPyCode( "Window.SetDimensions = wx.deprecated(Window.SetDimensions, 'Use SetSize instead.')" ) # Make the Register/UnregisterHotKey functions be available on Windows, # and empty stubs otherwise c.find('RegisterHotKey').setCppCode("""\ #if wxUSE_HOTKEY return self->RegisterHotKey(hotkeyId, modifiers, virtualKeyCode); #else return false; #endif """) c.find('UnregisterHotKey').setCppCode("""\ #if wxUSE_HOTKEY return self->UnregisterHotKey(hotkeyId); #else return false; #endif """) c.find('RegisterHotKey').isVirtual = False c.find('UnregisterHotKey').isVirtual = False c.find('SetDoubleBuffered').setCppCode("""\ #if defined(__WXGTK20__) || defined(__WXGTK3__) || defined(__WXMSW__) self->SetDoubleBuffered(on); #endif """) c.addPyMethod( '__nonzero__', '(self)', doc= "Can be used to test if the C++ part of the window still exists, with \n" "code like this::\n\n" " if theWindow:\n" " doSomething()", body="""\ import wx.siplib return not wx.siplib.isdeleted(self) """) c.addPyCode('Window.__bool__ = Window.__nonzero__') # For Python 3 c.addPyMethod('DestroyLater', '(self)', doc="""\ Schedules the window to be destroyed in the near future. This should be used whenever Destroy could happen too soon, such as when there may still be events for this window or its children waiting in the event queue. """, body="""\ self.Hide() wx.GetApp().ScheduleForDestruction(self) """) c.addPyMethod('DLG_UNIT', '(self, dlg_unit)', doc="""\ A convenience wrapper for :meth:`ConvertDialogToPixels`. """, body="""\ is_wxType = isinstance(dlg_unit, (wx.Size, wx.Point)) pix = self.ConvertDialogToPixels(dlg_unit) if not is_wxType: pix = tuple(pix) return pix """) # wxAccessbile is MSW only. Provide a NotImplemented fallback for the # other platforms. c.find('GetAccessible').setCppCode("""\ #if wxUSE_ACCESSIBILITY return self->GetAccessible(); #else wxPyRaiseNotImplemented(); return NULL; #endif """) c.find('SetAccessible.accessible').transfer = True c.find('SetAccessible').setCppCode("""\ #if wxUSE_ACCESSIBILITY self->SetAccessible(accessible); #else wxPyRaiseNotImplemented(); #endif """) # Make some of the protected methods visible and overridable from Python c.find('SendDestroyEvent').ignore(False) c.find('Destroy').transferThis = True c.addPyMethod('PostCreate', '(self, pre)', 'pass', deprecated='PostCreate is no longer necessary.') # transfer ownership of these parameters to the C++ object c.find('SetCaret.caret').transfer = True c.find('SetToolTip.tip').transfer = True c.find('SetDropTarget.target').transfer = True c.find('SetConstraints.constraints').transfer = True c.find('SetSizer.sizer').transfer = True c.find('SetSizerAndFit.sizer').transfer = True # Change some =0 default values to =NULL so the docs will make more sense c.find('FindWindowById.parent').default = 'NULL' c.find('FindWindowByLabel.parent').default = 'NULL' c.find('FindWindowByName.parent').default = 'NULL' # Transfer ownership of the wx.EvtHandler when pushing/popping them... c.find('PushEventHandler.handler').transfer = True c.find('PopEventHandler').transferBack = True # ...and for Set/RemoveEventHandler too c.find('SetEventHandler.handler').transfer = True c.find('RemoveEventHandler.handler').transferBack = True # Define some properties using the getter and setter methods c.addProperty('AcceleratorTable GetAcceleratorTable SetAcceleratorTable') c.addProperty('AutoLayout GetAutoLayout SetAutoLayout') c.addProperty('BackgroundColour GetBackgroundColour SetBackgroundColour') c.addProperty('BackgroundStyle GetBackgroundStyle SetBackgroundStyle') c.addProperty('EffectiveMinSize GetEffectiveMinSize') c.addProperty('BestSize GetBestSize') c.addProperty('BestVirtualSize GetBestVirtualSize') c.addProperty('Border GetBorder') c.addProperty('Caret GetCaret SetCaret') c.addProperty('CharHeight GetCharHeight') c.addProperty('CharWidth GetCharWidth') c.addProperty('Children GetChildren') c.addProperty('ClientAreaOrigin GetClientAreaOrigin') c.addProperty('ClientSize GetClientSize SetClientSize') c.addProperty('Constraints GetConstraints SetConstraints') c.addProperty('ContainingSizer GetContainingSizer SetContainingSizer') c.addProperty('Cursor GetCursor SetCursor') c.addProperty('DefaultAttributes GetDefaultAttributes') c.addProperty('DropTarget GetDropTarget SetDropTarget') c.addProperty('EventHandler GetEventHandler SetEventHandler') c.addProperty('ExtraStyle GetExtraStyle SetExtraStyle') c.addProperty('Font GetFont SetFont') c.addProperty('ForegroundColour GetForegroundColour SetForegroundColour') c.addProperty('GrandParent GetGrandParent') c.addProperty('TopLevelParent GetTopLevelParent') c.addProperty('Handle GetHandle') c.addProperty('HelpText GetHelpText SetHelpText') c.addProperty('Id GetId SetId') c.addProperty('Label GetLabel SetLabel') c.addProperty('LayoutDirection GetLayoutDirection SetLayoutDirection') c.addProperty('MaxHeight GetMaxHeight') c.addProperty('MaxSize GetMaxSize SetMaxSize') c.addProperty('MaxWidth GetMaxWidth') c.addProperty('MinHeight GetMinHeight') c.addProperty('MinSize GetMinSize SetMinSize') c.addProperty('MinWidth GetMinWidth') c.addProperty('Name GetName SetName') c.addProperty('Parent GetParent') c.addProperty('Position GetPosition SetPosition') c.addProperty('ScreenPosition GetScreenPosition') c.addProperty('ScreenRect GetScreenRect') c.addProperty('Size GetSize SetSize') c.addProperty('Sizer GetSizer SetSizer') c.addProperty('ThemeEnabled GetThemeEnabled SetThemeEnabled') c.addProperty('ToolTip GetToolTip SetToolTip') c.addProperty('UpdateClientRect GetUpdateClientRect') c.addProperty('UpdateRegion GetUpdateRegion') c.addProperty('Validator GetValidator SetValidator') c.addProperty('VirtualSize GetVirtualSize SetVirtualSize') c.addProperty('WindowStyle GetWindowStyle SetWindowStyle') c.addProperty('WindowStyleFlag GetWindowStyleFlag SetWindowStyleFlag') c.addProperty('WindowVariant GetWindowVariant SetWindowVariant') c.addProperty('Shown IsShown Show') c.addProperty('Enabled IsEnabled Enable') c.addProperty('TopLevel IsTopLevel') c.addProperty('MinClientSize GetMinClientSize SetMinClientSize') c.addProperty('MaxClientSize GetMaxClientSize SetMaxClientSize') ##c.addProperty('GtkWidget GetGtkWidget') tools.fixWindowClass(c) tools.addSipConvertToSubClassCode(c) # for compatibility with Classic c.addPyMethod('GetPositionTuple', '(self)', 'return self.GetPosition()', deprecated='Use GetPosition instead') c.addPyMethod('GetSizeTuple', '(self)', 'return self.GetSize()', deprecated='Use GetSize instead') c.addPyMethod('MoveXY', '(self, x, y)', 'return self.Move(x, y)', deprecated='Use Move instead.') c.addPyMethod('SetSizeWH', '(self, w, h)', 'return self.SetSize(w,h)', deprecated='Use SetSize instead.') c.addPyMethod('SetVirtualSizeWH', '(self, w, h)', 'return self.SetVirtualSize(w,h)', deprecated='Use SetVirtualSize instead.') c.addPyMethod('GetVirtualSizeTuple', '(self)', 'return self.GetVirtualSize()', deprecated='Use GetVirtualSize instead.') c.addPyMethod('SetToolTipString', '(self, string)', 'return self.SetToolTip(string)', deprecated='Use SetToolTip instead.') c.addPyMethod('ConvertDialogPointToPixels', '(self, point)', 'return self.ConvertDialogToPixels(point)', deprecated='Use ConvertDialogToPixels instead.') c.addPyMethod('ConvertDialogSizeToPixels', '(self, size)', 'return self.ConvertDialogToPixels(point)', deprecated='Use ConvertDialogToPixels instead.') c.addPyMethod( 'SetSizeHintsSz', '(self, minSize, maxSize=wx.DefaultSize, incSize=wx.DefaultSize)', 'return self.SetSizeHints(minSize, maxSize, incSize)', deprecated='Use SetSizeHints instead.') # TODO: the C++ DoEraseBackground is protected in wxMSW. We need a way to # unprotect it, like adding a shim in the sip class... #c.addHeaderCode("""\ # #ifdef __WXMSW__ # #include <wx/msw/dc.h> # #endif # """) #c.addCppMethod('bool', 'DoEraseBackground', '(wxDC* dc)', # doc="Default erase background implementation.", # body="""\ # #ifdef __WXMSW__ # return self->DoEraseBackground(((wxMSWDCImpl*)dc->GetImpl())->GetHDC()); # #else # dc->SetBackground(wxBrush(self->GetBackgroundColour())); # dc->Clear(); # return true; # #endif # """) # this is a nested class c.find('ChildrenRepositioningGuard').addPrivateCopyCtor() module.insertItem( 0, etgtools.TypedefDef(type='wxWindow::ChildrenRepositioningGuard', name='ChildrenRepositioningGuard')) #----------------------------------------------------------------------- # Other stuff module.addPyCode('''\ class FrozenWindow(object): """ A context manager to be used with Python 'with' statements that will freeze the given window for the duration of the with block. """ def __init__(self, window): self._win = window def __enter__(self): self._win.Freeze() return self def __exit__(self, exc_type, exc_val, exc_tb): self._win.Thaw() ''') module.addPyCode('''\ def DLG_UNIT(win, dlg_unit, val2=None): """ Convenience function for converting a wx.Point, wx.Size or (x,y) in dialog units to pixels, using the given window as a reference. """ if val2 is not None: dlg_unit = (dlg_unit, val2) is_wxType = isinstance(dlg_unit, (wx.Size, wx.Point)) pix = win.ConvertDialogToPixels(dlg_unit) if not is_wxType: pix = tuple(pix) return pix DLG_PNT = wx.deprecated(DLG_UNIT, "Use DLG_UNIT instead.") DLG_SZE = wx.deprecated(DLG_UNIT, "Use DLG_UNIT instead.") ''') # Add a wrapper for wxWindowList and a new iterator class for it that # makes wxWindowList quack like a read-only Python sequence. module.addItem( tools.wxListWrapperTemplate('wxWindowList', 'wxWindow', module)) module.addCppFunction( 'wxWindowList*', 'GetTopLevelWindows', '()', noCopy=True, briefDoc= "Returns a list-like object of the the application's top-level windows, (frames,dialogs, etc.)", body="return &wxTopLevelWindows;") module.addPyCode("PyWindow = wx.deprecated(Window, 'Use Window instead.')") module.find('wxFindWindowAtPointer.pt').out = True module.find('wxFindWindowAtPointer').mustHaveApp() module.find('wxGetActiveWindow').mustHaveApp() module.find('wxGetTopLevelParent').mustHaveApp() module.addCppFunction('wxWindow*', 'FindWindowById', '(long id, const wxWindow* parent=NULL)', doc="""\ FindWindowById(id, parent=None) -> Window Find the first window in the application with the given id. If parent is None, the search will start from all top-level frames and dialog boxes; if non-None, the search will be limited to the given window hierarchy. The search is recursive in both cases. """, body="return wxWindow::FindWindowById(id, parent);", mustHaveAppFlag=True) module.addCppFunction( 'wxWindow*', 'FindWindowByName', '(const wxString& name, const wxWindow* parent=NULL)', doc="""\ FindWindowByName(name, parent=None) -> Window Find a window by its name (as given in a window constructor or Create function call). If parent is None, the search will start from all top-level frames and dialog boxes; if non-None, the search will be limited to the given window hierarchy. The search is recursive in both cases. If no window with the name is found, wx.FindWindowByLabel is called.""", body="return wxWindow::FindWindowByName(*name, parent);", mustHaveAppFlag=True) module.addCppFunction( 'wxWindow*', 'FindWindowByLabel', '(const wxString& label, const wxWindow* parent=NULL)', doc="""\ FindWindowByLabel(label, parent=None) -> Window Find a window by its label. Depending on the type of window, the label may be a window title or panel item label. If parent is None, the search will start from all top-level frames and dialog boxes; if non-None, the search will be limited to the given window hierarchy. The search is recursive in both cases.""", body="return wxWindow::FindWindowByLabel(*label, parent);", mustHaveAppFlag=True) #----------------------------------------------------------------- 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('wxHtmlWindowInterface') assert isinstance(c, etgtools.ClassDef) c.find('OnHTMLOpeningURL.redirect').out = True c.find('OnHTMLOpeningURL.redirect').name = 'redirectTo' c = module.find('wxHtmlWindow') assert isinstance(c, etgtools.ClassDef) tools.fixWindowClass(c) c.bases = ['wxScrolledWindow', 'wxHtmlWindowInterface'] tools.fixHtmlSetFonts(c) c.find('AddFilter.filter').transfer = True c.find('OnOpeningURL.redirect').out = True c.find('OnOpeningURL.redirect').name = 'redirectTo' # Turn the virtual flag back on for some methods for name in [ 'OnLinkClicked', 'OnOpeningURL', 'OnSetTitle', 'OnCellMouseHover', 'OnCellClicked' ]: c.find(name).isVirtual = True c.find(name).ignore(False) # Declare that the pure virtuals inherited from wxHtmlWindowInterface have # implementations here c.addItem( etgtools.WigCode("""\ virtual void SetHTMLWindowTitle(const wxString& title); virtual void OnHTMLLinkClicked(const wxHtmlLinkInfo& link); virtual wxHtmlOpeningStatus OnHTMLOpeningURL(wxHtmlURLType type, const wxString& url, wxString *redirectTo /Out/) const; virtual wxPoint HTMLCoordsToWindow(wxHtmlCell *cell, const wxPoint& pos) const; virtual wxWindow* GetHTMLWindow(); virtual wxColour GetHTMLBackgroundColour() const; virtual void SetHTMLBackgroundColour(const wxColour& clr); virtual void SetHTMLBackgroundImage(const wxBitmap& bmpBg); virtual void SetHTMLStatusText(const wxString& text); virtual wxCursor GetHTMLCursor(wxHtmlWindowInterface::HTMLCursor type) const; """)) m = MethodDef(name='ScrollToAnchor', type='bool', protection='protected', items=[ParamDef(type='const wxString&', name='anchor')], doc="""\ Scrolls to anchor of this name. Returns True is anchor exists, False otherwise. """) c.addItem(m) c = module.find('wxHtmlLinkEvent') tools.fixEventClass(c) c = module.find('wxHtmlCellEvent') tools.fixEventClass(c) module.addPyCode("""\ EVT_HTML_CELL_CLICKED = wx.PyEventBinder( wxEVT_HTML_CELL_CLICKED, 1 ) EVT_HTML_CELL_HOVER = wx.PyEventBinder( wxEVT_HTML_CELL_HOVER, 1 ) EVT_HTML_LINK_CLICKED = wx.PyEventBinder( wxEVT_HTML_LINK_CLICKED, 1 ) # deprecated wxEVT aliases wxEVT_COMMAND_HTML_CELL_CLICKED = wxEVT_HTML_CELL_CLICKED wxEVT_COMMAND_HTML_CELL_HOVER = wxEVT_HTML_CELL_HOVER wxEVT_COMMAND_HTML_LINK_CLICKED = wxEVT_HTML_LINK_CLICKED """) #----------------------------------------------------------------- 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) module.check4unittest = False #----------------------------------------------------------------- # Tweak the parsed meta objects in the module object as needed for # customizing the generated code and docstrings. module.addHeaderCode('#include <wxpy_api.h>') module.addImport('_core') module.addImport('_xml') module.addPyCode('import wx', order=10) module.addInclude(INCLUDES) module.addInitializerCode("""\ //wxXmlInitResourceModule(); wxXmlResource::Get()->InitAllHandlers(); """) module.addHeaderCode('#include <wx/xrc/xmlres.h>') module.addHeaderCode('#include <wx/fs_mem.h>') module.addHeaderCode('#include "wxpybuffer.h"') module.insertItem( 0, etgtools.WigCode("""\ // forward declarations class wxAnimation; """)) #----------------------------------------------------------------- c = module.find('wxXmlResource') assert isinstance(c, etgtools.ClassDef) c.addPrivateCopyCtor() # Add a bit of code to the ctors to call InitAllHandlers(), for # compatibility with Classic for ctor in c.find('wxXmlResource').all(): template = """\ Py_BEGIN_ALLOW_THREADS sipCpp = new sipwxXmlResource({args}); sipCpp->InitAllHandlers(); Py_END_ALLOW_THREADS """ if 'filemask' in ctor.argsString: args = '*filemask,flags,*domain' else: args = 'flags,*domain' ctor.setCppCode_sip(template.format(args=args)) c.addPublic() c.addCppMethod( 'bool', 'LoadFromString', '(wxPyBuffer* data)', doc= "Load the resource from a string or other data buffer compatible object.", #protection='public', body="""\ static int s_memFileIdx = 0; // Check for memory FS. If not present, load the handler: wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy data")); wxFileSystem fsys; wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); if (f) delete f; else wxFileSystem::AddHandler(new wxMemoryFSHandler); // Now put the resource data into the memory FS wxString filename(wxT("XRC_resource/data_string_")); filename << s_memFileIdx; s_memFileIdx += 1; wxMemoryFSHandler::AddFile(filename, data->m_ptr, data->m_len); // Load the "file" into the resource object bool retval = self->Load(wxT("memory:") + filename ); return retval; """) c.find('AddHandler.handler').transfer = True c.find('InsertHandler.handler').transfer = True c.find('Set.res').transfer = True c.find('Set').transferBack = True c.find('AddSubclassFactory.factory').transfer = True #----------------------------------------------------------------- c = module.find('wxXmlResourceHandler') # un-ignore all the protected methods for item in c.allItems(): if isinstance(item, etgtools.MethodDef): item.ignore(False) c.find('DoCreateResource').factory = True #----------------------------------------------------------------- module.addPyFunction( 'EmptyXmlResource', '(flags=XRC_USE_LOCALE, domain="")', deprecated="Use :class:`xrc.XmlResource` instead", doc= 'A compatibility wrapper for the XmlResource(flags, domain) constructor', body='return XmlResource(flags, domain)') module.addPyFunction( 'XRCID', '(str_id, value_if_not_found=wx.ID_NONE)', doc= 'Returns a numeric ID that is equivalent to the string ID used in an XML resource.', body='return XmlResource.GetXRCID(str_id, value_if_not_found)') module.addPyFunction( 'XRCCTRL', '(window, str_id, *ignoreargs)', doc= 'Returns the child window associated with the string ID in an XML resource.', body='return window.FindWindowById(XRCID(str_id))') cls = ClassDef(name='wxXmlSubclassFactory', briefDoc="", items=[ MethodDef(name='wxXmlSubclassFactory', isCtor=True), MethodDef(name='~wxXmlSubclassFactory', isDtor=True), MethodDef(name='Create', type='wxObject*', isVirtual=True, isPureVirtual=True, items=[ ParamDef(type='const wxString&', name='className') ]) ]) module.addItem(cls) module.addPyCode("""\ # Create a factory for handling the subclass property of XRC's # object tag. This factory will search for the specified # package.module.class and will try to instantiate it for XRC's # use. The class must support instantiation with no parameters and # delayed creation of the UI widget (aka 2-phase create). def _my_import(name): try: mod = __import__(name) except ImportError: import traceback print traceback.format_exc() raise components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod class XmlSubclassFactory_Python(XmlSubclassFactory): def __init__(self): XmlSubclassFactory.__init__(self) def Create(self, className): assert className.find('.') != -1, "Module name must be specified!" mname = className[:className.rfind('.')] cname = className[className.rfind('.')+1:] module = _my_import(mname) klass = getattr(module, cname) inst = klass() return inst XmlResource.AddSubclassFactory(XmlSubclassFactory_Python()) """) #----------------------------------------------------------------- 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('wxTreeItemId') assert isinstance(c, etgtools.ClassDef) # add the void* ctor missing from the interface ctor = MethodDef(name='wxTreeItemId', isCtor=True, items=[ParamDef(name='pItem', type='void*')]) # add it as an overload to the existing ctor c.find('wxTreeItemId').overloads.append(ctor) c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();") c.addCppMethod('int', '__bool__', '()', "return self->IsOk();") c.addCppMethod('bool', '__eq__', '(const wxTreeItemId& other)', """\ return *self == *other; """) c.addCppMethod('bool', '__ne__', '(const wxTreeItemId& other)', """\ return *self != *other; """) c.addPyMethod('__hash__', '(self)', """\ return hash(int(self.GetID())) """) module.find('operator==').ignore() module.find('operator!=').ignore() td = etgtools.TypedefDef(name='wxTreeItemIdValue', type='void*') module.insertItemBefore(c, td) #------------------------------------------------------- module.addPyCode("""\ def TreeItemData(data): return data TreeItemData = deprecated(TreeItemData, "The TreeItemData class no longer exists, just pass your object directly to the tree instead.") """) #------------------------------------------------------- c = module.find('wxTreeCtrl') tools.fixWindowClass(c) module.addGlobalStr('wxTreeCtrlNameStr', before=c) tools.addEnableSystemTheme(c, 'wx.TreeCtrl') # Set all wxTreeItemData parameters to transfer ownership. Is this still needed with MappedTypes? for item in c.allItems(): if hasattr(item, 'type') and item.type == 'wxTreeItemData *' and \ isinstance(item, etgtools.ParamDef): item.transfer = True c.addPyCode("""\ TreeCtrl.GetItemPyData = wx.deprecated(TreeCtrl.GetItemData, 'Use GetItemData instead.') TreeCtrl.SetItemPyData = wx.deprecated(TreeCtrl.SetItemData, 'Use SetItemData instead.') TreeCtrl.GetPyData = wx.deprecated(TreeCtrl.GetItemData, 'Use GetItemData instead.') TreeCtrl.SetPyData = wx.deprecated(TreeCtrl.SetItemData, 'Use SetItemData instead.') """) # We can't use wxClassInfo c.find('EditLabel.textCtrlClass').ignore() # Replace GetSelections with a method that returns a Python list # size_t GetSelections(wxArrayTreeItemIds& selection) const; c.find('GetSelections').ignore() c.addCppMethod( 'PyObject*', 'GetSelections', '()', doc= 'Returns a list of currently selected items in the tree. This function ' 'can be called only if the control has the wx.TR_MULTIPLE style.', body="""\ wxPyThreadBlocker blocker; PyObject* rval = PyList_New(0); wxArrayTreeItemIds array; size_t num, x; num = self->GetSelections(array); for (x=0; x < num; x++) { wxTreeItemId *tii = new wxTreeItemId(array.Item(x)); PyObject* item = wxPyConstructObject((void*)tii, wxT("wxTreeItemId"), true); PyList_Append(rval, item); Py_DECREF(item); } return rval; """) # Change GetBoundingRect to return the rectangle instead of modifying the parameter. #bool GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool textOnly = false) const; c.find('GetBoundingRect').ignore() c.addCppMethod('PyObject*', 'GetBoundingRect', '(const wxTreeItemId& item, bool textOnly=false)', doc="""\ Returns the rectangle bounding the item. If textOnly is true, only the rectangle around the item's label will be returned, otherwise the item's image is also taken into account. The return value may be None if the rectangle was not successfully retrieved, such as if the item is currently not visible. """, isFactory=True, body="""\ wxRect rect; if (self->GetBoundingRect(*item, rect, textOnly)) { wxPyThreadBlocker blocker; wxRect* r = new wxRect(rect); PyObject* val = wxPyConstructObject((void*)r, wxT("wxRect"), true); return val; } else RETURN_NONE(); """) # switch the virtualness back on for those methods that need to have it. c.find('OnCompareItems').isVirtual = True # transfer imagelist ownership c.find('AssignStateImageList.imageList').transfer = True c.find('AssignButtonsImageList.imageList').transfer = True # Make the cookie values be returned, instead of setting it through the parameter c.find('GetFirstChild.cookie').out = True c.find('GetNextChild.cookie').inOut = True # TODO: These don't exist on MSW, Are they important enough that we # should provide them for the other platforms anyway? c.find('AssignButtonsImageList').ignore() c.find('GetButtonsImageList').ignore() c.find('SetButtonsImageList').ignore() #------------------------------------------------------- c = module.find('wxTreeEvent') tools.fixEventClass(c) module.addPyCode("""\ EVT_TREE_BEGIN_DRAG = PyEventBinder(wxEVT_TREE_BEGIN_DRAG , 1) EVT_TREE_BEGIN_RDRAG = PyEventBinder(wxEVT_TREE_BEGIN_RDRAG , 1) EVT_TREE_BEGIN_LABEL_EDIT = PyEventBinder(wxEVT_TREE_BEGIN_LABEL_EDIT , 1) EVT_TREE_END_LABEL_EDIT = PyEventBinder(wxEVT_TREE_END_LABEL_EDIT , 1) EVT_TREE_DELETE_ITEM = PyEventBinder(wxEVT_TREE_DELETE_ITEM , 1) EVT_TREE_GET_INFO = PyEventBinder(wxEVT_TREE_GET_INFO , 1) EVT_TREE_SET_INFO = PyEventBinder(wxEVT_TREE_SET_INFO , 1) EVT_TREE_ITEM_EXPANDED = PyEventBinder(wxEVT_TREE_ITEM_EXPANDED , 1) EVT_TREE_ITEM_EXPANDING = PyEventBinder(wxEVT_TREE_ITEM_EXPANDING , 1) EVT_TREE_ITEM_COLLAPSED = PyEventBinder(wxEVT_TREE_ITEM_COLLAPSED , 1) EVT_TREE_ITEM_COLLAPSING = PyEventBinder(wxEVT_TREE_ITEM_COLLAPSING , 1) EVT_TREE_SEL_CHANGED = PyEventBinder(wxEVT_TREE_SEL_CHANGED , 1) EVT_TREE_SEL_CHANGING = PyEventBinder(wxEVT_TREE_SEL_CHANGING , 1) EVT_TREE_KEY_DOWN = PyEventBinder(wxEVT_TREE_KEY_DOWN , 1) EVT_TREE_ITEM_ACTIVATED = PyEventBinder(wxEVT_TREE_ITEM_ACTIVATED , 1) EVT_TREE_ITEM_RIGHT_CLICK = PyEventBinder(wxEVT_TREE_ITEM_RIGHT_CLICK , 1) EVT_TREE_ITEM_MIDDLE_CLICK = PyEventBinder(wxEVT_TREE_ITEM_MIDDLE_CLICK, 1) EVT_TREE_END_DRAG = PyEventBinder(wxEVT_TREE_END_DRAG , 1) EVT_TREE_STATE_IMAGE_CLICK = PyEventBinder(wxEVT_TREE_STATE_IMAGE_CLICK, 1) EVT_TREE_ITEM_GETTOOLTIP = PyEventBinder(wxEVT_TREE_ITEM_GETTOOLTIP, 1) EVT_TREE_ITEM_MENU = PyEventBinder(wxEVT_TREE_ITEM_MENU, 1) # deprecated wxEVT aliases wxEVT_COMMAND_TREE_BEGIN_DRAG = wxEVT_TREE_BEGIN_DRAG wxEVT_COMMAND_TREE_BEGIN_RDRAG = wxEVT_TREE_BEGIN_RDRAG wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT = wxEVT_TREE_BEGIN_LABEL_EDIT wxEVT_COMMAND_TREE_END_LABEL_EDIT = wxEVT_TREE_END_LABEL_EDIT wxEVT_COMMAND_TREE_DELETE_ITEM = wxEVT_TREE_DELETE_ITEM wxEVT_COMMAND_TREE_GET_INFO = wxEVT_TREE_GET_INFO wxEVT_COMMAND_TREE_SET_INFO = wxEVT_TREE_SET_INFO wxEVT_COMMAND_TREE_ITEM_EXPANDED = wxEVT_TREE_ITEM_EXPANDED wxEVT_COMMAND_TREE_ITEM_EXPANDING = wxEVT_TREE_ITEM_EXPANDING wxEVT_COMMAND_TREE_ITEM_COLLAPSED = wxEVT_TREE_ITEM_COLLAPSED wxEVT_COMMAND_TREE_ITEM_COLLAPSING = wxEVT_TREE_ITEM_COLLAPSING wxEVT_COMMAND_TREE_SEL_CHANGED = wxEVT_TREE_SEL_CHANGED wxEVT_COMMAND_TREE_SEL_CHANGING = wxEVT_TREE_SEL_CHANGING wxEVT_COMMAND_TREE_KEY_DOWN = wxEVT_TREE_KEY_DOWN wxEVT_COMMAND_TREE_ITEM_ACTIVATED = wxEVT_TREE_ITEM_ACTIVATED wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK = wxEVT_TREE_ITEM_RIGHT_CLICK wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK = wxEVT_TREE_ITEM_MIDDLE_CLICK wxEVT_COMMAND_TREE_END_DRAG = wxEVT_TREE_END_DRAG wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK = wxEVT_TREE_STATE_IMAGE_CLICK wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP = wxEVT_TREE_ITEM_GETTOOLTIP wxEVT_COMMAND_TREE_ITEM_MENU = wxEVT_TREE_ITEM_MENU """) #----------------------------------------------------------------- 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) #----------------------------------------------------------------- # The wxPyAxBaseWindow class does not come from the parsed Doxygen xml, # instead it is manufactured entirely in this ETG script. We're doing it # here instead of in a raw .sip file so we can run the generators on it # and get things like documentation and .pyi files generated like any # normal class. # First, output some C++ code module.addHeaderCode("""\ class wxPyAxBaseWindow : public wxWindow { DECLARE_DYNAMIC_CLASS(wxPyAxBaseWindow) public: wxPyAxBaseWindow(wxWindow* parent, const wxWindowID id=-1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxPanelNameStr) : wxWindow(parent, id, pos, size, style, name) {} wxPyAxBaseWindow() : wxWindow() {} virtual bool MSWTranslateMessage(WXMSG* msg) { return wxWindow::MSWTranslateMessage(msg); } }; """) module.addCppCode("""\ IMPLEMENT_DYNAMIC_CLASS(wxPyAxBaseWindow, wxWindow); """) # Now create the extractor objects that will be run through the generators module.addItem(TypedefDef(type='void', name='WXMSG')) cls = ClassDef(name='wxPyAxBaseWindow', bases=['wxWindow'], briefDoc="""\ A Window class for use with ActiveX controls. This Window class exposes some low-level Microsoft Windows specific methods which can be overridden in Python. Intended for use as an ActiveX container, but could also be useful elsewhere.""", items=[ MethodDef(name='wxPyAxBaseWindow', isCtor=True, items=[ ParamDef(type='wxWindow*', name='parent'), ParamDef(type='const wxWindowID', name='id', default='-1'), ParamDef(type='const wxPoint&', name='pos', default='wxDefaultPosition'), ParamDef(type='const wxSize&', name='size', default='wxDefaultSize'), ParamDef(type='long', name='style', default='0'), ParamDef(type='const wxString&', name='name', default='wxPanelNameStr'), ], overloads=[ MethodDef(name='wxPyAxBaseWindow', isCtor=True), ]), MethodDef(type='bool', name='MSWTranslateMessage', isVirtual=True, items=[ParamDef(type='WXMSG*', name='msg')]) ]) module.addItem(cls) #----------------------------------------------------------------- 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('wxWindow') assert isinstance(c, etgtools.ClassDef) module.addGlobalStr('wxPanelNameStr', c) # First we need to let the wrapper generator know about wxWindowBase since # AddChild and RemoveChild need to use that type in order to be virtualized. winbase = ClassDef(name='wxWindowBase', bases=['wxEvtHandler'], abstract=True, items=[MethodDef(name='AddChild', isVirtual=True, type='void', protection='public', items=[ParamDef(name='child', type='wxWindowBase*')]), MethodDef(name='RemoveChild', isVirtual=True, type='void', protection='public', items=[ParamDef(name='child', type='wxWindowBase*')]) ]) module.insertItemBefore(c, winbase) # Now change the base class of wxWindow c.bases = ['wxWindowBase'] # And fix the arg types we get from Doxy c.find('AddChild.child').type = 'wxWindowBase*' c.find('RemoveChild.child').type = 'wxWindowBase*' # We now return you to our regularly scheduled programming... c.includeCppCode('src/window_ex.cpp') # ignore some overloads that will be ambiguous afer wrapping c.find('GetChildren').overloads = [] c.find('GetChildren').noCopy = True c.find('GetClientSize').findOverload('int *').ignore() c.find('GetSize').findOverload('int *').ignore() c.find('GetVirtualSize').findOverload('int *').ignore() c.find('GetPosition').findOverload('int *').ignore() c.find('GetScreenPosition').findOverload('int *').ignore() c.find('ClientToScreen').findOverload('int *').ignore() c.find('ScreenToClient').findOverload('int *').ignore() # Release the GIL for potentially blocking or long-running functions c.find('PopupMenu').releaseGIL() c.find('ProcessEvent').releaseGIL() c.find('ProcessWindowEvent').releaseGIL() c.find('ProcessWindowEventLocally').releaseGIL() # Add a couple wrapper functions for symmetry with the getters of the same name c.addPyMethod('SetRect', '(self, rect)', 'return self.SetSize(rect)') c.addPyProperty('Rect GetRect SetRect') c.addPyMethod('SetClientRect', '(self, rect)', 'return self.SetClientSize(rect)') c.addPyProperty('ClientRect GetClientRect SetClientRect') m = c.find('GetTextExtent').findOverload('int *') m.pyName = 'GetFullTextExtent' m.find('w').out = True m.find('h').out = True m.find('descent').out = True m.find('externalLeading').out = True c.find('GetHandle').type = 'unsigned long' c.find('GetHandle').setCppCode("return wxPyGetWinHandle(self);") c.addCppMethod('void*', 'GetGtkWidget', '()', """\ #ifdef __WXGTK__ return (void*)self->GetHandle(); #else return NULL; #endif """) c.addCppMethod('void', 'AssociateHandle', '(long handle)', doc="Associate the window with a new native handle", body="self->AssociateHandle((WXWidget)handle);") c.addCppMethod('void', 'DissociateHandle', '()', doc="Dissociate the current native handle from the window", body="self->DissociateHandle();") # Add some new methods c.addCppMethod('wxWindow*', 'GetTopLevelParent', '()', 'return wxGetTopLevelParent(self);', briefDoc="Returns the first ancestor of this window which is a top-level window.") c.addCppMethod('bool', 'MacIsWindowScrollbar', '(const wxWindow* sb)', """\ #ifdef __WXMAC__ return self->MacIsWindowScrollbar(sb); #else return false; #endif """, pyArgsString="(sb)", briefDoc="Is the given widget one of this window's built-in scrollbars? Only applicable on Mac.") c.addCppMethod('void', 'SetDimensions', '(int x, int y, int width, int height, int sizeFlags=wxSIZE_AUTO)', pyArgsString="(x, y, width, height, sizeFlags=SIZE_AUTO)", body="""\ self->SetSize(x, y, width, height, sizeFlags); """) c.addPyCode("Window.SetDimensions = wx.deprecated(Window.SetDimensions, 'Use SetSize instead.')") # Make the Register/UnregisterHotKey functions be available on Windows, # and empty stubs otherwise c.find('RegisterHotKey').setCppCode("""\ #if wxUSE_HOTKEY return self->RegisterHotKey(hotkeyId, modifiers, virtualKeyCode); #else return false; #endif """) c.find('UnregisterHotKey').setCppCode("""\ #if wxUSE_HOTKEY return self->UnregisterHotKey(hotkeyId); #else return false; #endif """) c.find('RegisterHotKey').isVirtual = False c.find('UnregisterHotKey').isVirtual = False c.find('SetDoubleBuffered').setCppCode("""\ #if defined(__WXGTK20__) || defined(__WXMSW__) self->SetDoubleBuffered(on); #endif """) c.addPyMethod('__nonzero__', '(self)', doc="Can be used to test if the C++ part of the window still exists, with \n" "code like this::\n\n" " if theWindow:\n" " doSomething()", body="""\ import wx.siplib return not wx.siplib.isdeleted(self) """) c.addPyCode('Window.__bool__ = Window.__nonzero__') # For Python 3 c.addPyMethod('DestroyLater', '(self)', doc="""\ Schedules the window to be destroyed in the near future. This should be used whenever Destroy could happen too soon, such as when there may still be events for this window or its children waiting in the event queue. """, body="""\ self.Hide() wx.GetApp().ScheduleForDestruction(self) """) # MSW only. Do we want them wrapped? c.find('GetAccessible').ignore() c.find('SetAccessible').ignore() # Make some of the protected methods visible and overridable from Python c.find('SendDestroyEvent').ignore(False) c.find('Destroy').transferThis=True c.addPyMethod('PostCreate', '(self, pre)', 'pass', deprecated='PostCreate is no longer necessary.') # transfer ownership of these parameters to the C++ object c.find('SetCaret.caret').transfer = True c.find('SetToolTip.tip').transfer = True c.find('SetDropTarget.target').transfer = True c.find('SetConstraints.constraints').transfer = True c.find('SetSizer.sizer').transfer = True c.find('SetSizerAndFit.sizer').transfer = True # Define some properties using the getter and setter methods c.addProperty('AcceleratorTable GetAcceleratorTable SetAcceleratorTable') c.addProperty('AutoLayout GetAutoLayout SetAutoLayout') c.addProperty('BackgroundColour GetBackgroundColour SetBackgroundColour') c.addProperty('BackgroundStyle GetBackgroundStyle SetBackgroundStyle') c.addProperty('EffectiveMinSize GetEffectiveMinSize') c.addProperty('BestSize GetBestSize') c.addProperty('BestVirtualSize GetBestVirtualSize') c.addProperty('Border GetBorder') c.addProperty('Caret GetCaret SetCaret') c.addProperty('CharHeight GetCharHeight') c.addProperty('CharWidth GetCharWidth') c.addProperty('Children GetChildren') c.addProperty('ClientAreaOrigin GetClientAreaOrigin') c.addProperty('ClientSize GetClientSize SetClientSize') c.addProperty('Constraints GetConstraints SetConstraints') c.addProperty('ContainingSizer GetContainingSizer SetContainingSizer') c.addProperty('Cursor GetCursor SetCursor') c.addProperty('DefaultAttributes GetDefaultAttributes') c.addProperty('DropTarget GetDropTarget SetDropTarget') c.addProperty('EventHandler GetEventHandler SetEventHandler') c.addProperty('ExtraStyle GetExtraStyle SetExtraStyle') c.addProperty('Font GetFont SetFont') c.addProperty('ForegroundColour GetForegroundColour SetForegroundColour') c.addProperty('GrandParent GetGrandParent') c.addProperty('TopLevelParent GetTopLevelParent') c.addProperty('Handle GetHandle') c.addProperty('HelpText GetHelpText SetHelpText') c.addProperty('Id GetId SetId') c.addProperty('Label GetLabel SetLabel') c.addProperty('LayoutDirection GetLayoutDirection SetLayoutDirection') c.addProperty('MaxHeight GetMaxHeight') c.addProperty('MaxSize GetMaxSize SetMaxSize') c.addProperty('MaxWidth GetMaxWidth') c.addProperty('MinHeight GetMinHeight') c.addProperty('MinSize GetMinSize SetMinSize') c.addProperty('MinWidth GetMinWidth') c.addProperty('Name GetName SetName') c.addProperty('Parent GetParent') c.addProperty('Position GetPosition SetPosition') c.addProperty('ScreenPosition GetScreenPosition') c.addProperty('ScreenRect GetScreenRect') c.addProperty('Size GetSize SetSize') c.addProperty('Sizer GetSizer SetSizer') c.addProperty('ThemeEnabled GetThemeEnabled SetThemeEnabled') c.addProperty('ToolTip GetToolTip SetToolTip') c.addProperty('UpdateClientRect GetUpdateClientRect') c.addProperty('UpdateRegion GetUpdateRegion') c.addProperty('Validator GetValidator SetValidator') c.addProperty('VirtualSize GetVirtualSize SetVirtualSize') c.addProperty('WindowStyle GetWindowStyle SetWindowStyle') c.addProperty('WindowStyleFlag GetWindowStyleFlag SetWindowStyleFlag') c.addProperty('WindowVariant GetWindowVariant SetWindowVariant') c.addProperty('Shown IsShown Show') c.addProperty('Enabled IsEnabled Enable') c.addProperty('TopLevel IsTopLevel') c.addProperty('MinClientSize GetMinClientSize SetMinClientSize') c.addProperty('MaxClientSize GetMaxClientSize SetMaxClientSize') ##c.addProperty('GtkWidget GetGtkWidget') tools.fixWindowClass(c) tools.addSipConvertToSubClassCode(c) # for compatibility with Classic c.addPyMethod('GetPositionTuple', '(self)', 'return self.GetPosition()', deprecated='Use GetPosition instead') c.addPyMethod('MoveXY', '(self, x, y)', 'return self.Move(x, y)', deprecated='Use Move instead.') c.addPyMethod('SetSizeWH', '(self, w, h)', 'return self.SetSize(w,h)', deprecated='Use SetSize instead.') c.addPyMethod('SetVirtualSizeWH', '(self, w, h)', 'return self.SetVirtualSize(w,h)', deprecated='Use SetVirtualSize instead.') c.addPyMethod('GetVirtualSizeTuple', '(self)', 'return self.GetVirtualSize()', deprecated='Use GetVirtualSize instead.') c.addPyMethod('SetToolTipString', '(self, string)', 'return self.SetToolTip(string)', deprecated='Use SetToolTip instead.') c.addPyMethod('ConvertDialogPointToPixels', '(self, point)', 'return self.ConvertDialogToPixels(point)', deprecated='Use ConvertDialogToPixels instead.') c.addPyMethod('ConvertDialogSizeToPixels', '(self, size)', 'return self.ConvertDialogToPixels(point)', deprecated='Use ConvertDialogToPixels instead.') # this is a nested class c.find('ChildrenRepositioningGuard').addPrivateCopyCtor() module.insertItem(0, etgtools.TypedefDef(type='wxWindow::ChildrenRepositioningGuard', name='ChildrenRepositioningGuard')) #----------------------------------------------------------------------- # Other stuff module.addPyCode('''\ class FrozenWindow(object): """ A context manager to be used with Python 'with' statements that will freeze the given window for the duration of the with block. """ def __init__(self, window): self._win = window def __enter__(self): self._win.Freeze() return self def __exit__(self, exc_type, exc_val, exc_tb): self._win.Thaw() ''') # Add a wrapper for wxWindowList and a new iterator class for it that # makes wxWindowList quack like a read-only Python sequence. module.addItem(tools.wxListWrapperTemplate('wxWindowList', 'wxWindow', module)) module.addCppFunction('wxWindowList*', 'GetTopLevelWindows', '()', noCopy=True, briefDoc="Returns a list-like object of the the application's top-level windows, (frames,dialogs, etc.)", body="return &wxTopLevelWindows;") module.addPyCode("PyWindow = wx.deprecated(Window, 'Use Window instead.')") module.find('wxFindWindowAtPointer.pt').out = True module.addCppFunction('wxWindow*', 'FindWindowById', '(long id, const wxWindow* parent=NULL)', doc="""\ FindWindowById(id, parent=None) -> Window Find the first window in the application with the given id. If parent is None, the search will start from all top-level frames and dialog boxes; if non-None, the search will be limited to the given window hierarchy. The search is recursive in both cases. """, body="return wxWindow::FindWindowById(id, parent);") module.addCppFunction('wxWindow*', 'FindWindowByName', '(const wxString& name, const wxWindow* parent=NULL)', doc="""\ FindWindowByName(name, parent=None) -> Window Find a window by its name (as given in a window constructor or Create function call). If parent is None, the search will start from all top-level frames and dialog boxes; if non-None, the search will be limited to the given window hierarchy. The search is recursive in both cases. If no window with the name is found, wx.FindWindowByLabel is called.""", body="return wxWindow::FindWindowByName(*name, parent);") module.addCppFunction('wxWindow*', 'FindWindowByLabel', '(const wxString& label, const wxWindow* parent=NULL)', doc="""\ FindWindowByLabel(label, parent=None) -> Window Find a window by its label. Depending on the type of window, the label may be a window title or panel item label. If parent is None, the search will start from all top-level frames and dialog boxes; if non-None, the search will be limited to the given window hierarchy. The search is recursive in both cases.""", body="return wxWindow::FindWindowByLabel(*label, parent);") #----------------------------------------------------------------- tools.doCommonTweaks(module) tools.runGenerators(module)