def changeTypeNames(module, oldName, newName, skipTypedef=False): """ Changes the matching type names for functions and parameters to a new name, and optionally adds typedefs for the new name as well. """ if not skipTypedef: module.addHeaderCode("typedef {old} {new};".format(old=oldName, new=newName)) module.addItem(extractors.TypedefDef(type=oldName, name=newName)) for item in module.allItems(): if isinstance(item, (extractors.FunctionDef, extractors.ParamDef)) and \ hasattr(item, 'type') and oldName in item.type: item.type = item.type.replace(oldName, newName)
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. module.addGlobalStr('wxGridNameStr', module.items[0]) module.addPyCode("""\ GRID_VALUE_STRING = "string" GRID_VALUE_BOOL = "bool" GRID_VALUE_NUMBER = "long" GRID_VALUE_FLOAT = "double" GRID_VALUE_CHOICE = "choice" GRID_VALUE_DATE = "date" GRID_VALUE_TEXT = "string" GRID_VALUE_LONG = "long" GRID_VALUE_CHOICEINT = "choiceint" GRID_VALUE_DATETIME = "datetime" """) # Add compatibility constants for these since they've been removed from wxWidgets # TODO: Remove these in a future release. module.addPyCode("""\ GRIDTABLE_REQUEST_VIEW_GET_VALUES = 2000 GRIDTABLE_REQUEST_VIEW_SEND_VALUES = 2001 """) module.insertItem( 0, etgtools.TypedefDef(type='wxWindow', name='wxGridWindow')) #----------------------------------------------------------------- c = module.find('wxGridCellCoords') assert isinstance(c, etgtools.ClassDef) tools.addAutoProperties(c) c.find('operator!').ignore() c.find('operator=').ignore() # Add a typemap for 2 element sequences c.convertFromPyObject = tools.convertTwoIntegersTemplate( 'wxGridCellCoords') c.addCppMethod('PyObject*', 'Get', '()', """\ wxPyThreadBlocker blocker; return sipBuildResult(0, "(ii)", self->GetRow(), self->GetCol()); """, pyArgsString="() -> (row,col)", briefDoc="Return the row and col properties as a tuple.") tools.addGetIMMethodTemplate(module, c, ['Row', 'Col']) # Add sequence protocol methods and other goodies c.addPyMethod('__str__', '(self)', 'return str(self.Get())') c.addPyMethod('__repr__', '(self)', 'return "GridCellCoords"+str(self.Get())') c.addPyMethod('__len__', '(self)', 'return len(self.Get())') c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)') c.addPyMethod('__bool__', '(self)', 'return self.Get() != (0,0)') c.addPyMethod('__reduce__', '(self)', 'return (GridCellCoords, self.Get())') c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]') c.addPyMethod( '__setitem__', '(self, idx, val)', """\ if idx == 0: self.Row = val elif idx == 1: self.Col = val else: raise IndexError """) c.addPyCode('GridCellCoords.__safe_for_unpickling__ = True') module.addItem( tools.wxArrayWrapperTemplate('wxGridCellCoordsArray', 'wxGridCellCoords', module, getItemCopy=True)) #----------------------------------------------------------------- c = module.find('wxGridBlockCoords') tools.addAutoProperties(c) c.find('operator!').ignore() c.addCppMethod('int', '__bool__', '()', "return self->operator!();") c.addCppMethod('PyObject*', 'Get', '()', """\ wxPyThreadBlocker blocker; return sipBuildResult(0, "(iiii)", self->GetTopRow(), self->GetLeftCol(), self->GetBottomRow(), self->GetRightCol()); """, pyArgsString="() -> (topRow, leftCol, bottomRow, rightCol)", briefDoc="Return the block coordinants as a tuple.") c.addPyMethod('__str__', '(self)', 'return str(self.Get())') c.addPyMethod('__repr__', '(self)', 'return "GridBlockCoords"+str(self.Get())') #----------------------------------------------------------------- c = module.find('wxGridBlockDiffResult') c.find('m_parts').ignore() c.addCppMethod( 'PyObject*', '_getParts', '()', """\ wxPyThreadBlocker blocker; PyObject* ret = PyTuple_New(4); if (ret) { PyTuple_SET_ITEM(ret, 0, wxPyConstructObject(&self->m_parts[0], "wxGridBlockCoords", false)); PyTuple_SET_ITEM(ret, 1, wxPyConstructObject(&self->m_parts[1], "wxGridBlockCoords", false)); PyTuple_SET_ITEM(ret, 2, wxPyConstructObject(&self->m_parts[2], "wxGridBlockCoords", false)); PyTuple_SET_ITEM(ret, 3, wxPyConstructObject(&self->m_parts[3], "wxGridBlockCoords", false)); } return ret; """) c.addProperty('m_parts', '_getParts') #----------------------------------------------------------------- c = module.find('wxGridBlocks') c.addPrivateDefaultCtor() c.addPrivateAssignOp() c.addPyMethod( '__iter__', '(self)', 'return PyGridBlocksIterator(self)', "Returns a Python iterator for accessing the collection of grid blocks." ) # This class is the Python iterator that knows how to fetch blocks from the # wxGridBlocks object c.addPyCode("""\ class PyGridBlocksIterator(object): "A Python iterator for GridBlocks objects" def __init__(self, blocks): self._blocks = blocks self._iterator = self._blocks.begin() def __next__(self): if self._iterator == self._blocks.end(): raise StopIteration obj = self._iterator._get() self._iterator = self._iterator._next() return obj """) # c.find('iterator').addCppMethod('wxGridBlocks::iterator', '_next', '()', # "return self->operator++();") # c.find('iterator').addCppMethod('const wxGridBlockCoords&', '_get', '()', # "return self->operator*();") # TODO: Doing these the normal way (above) breaks because it tries to use just # "iterator" for the self param type, instead of wxGridBlocks::iterator. # That should be fixable, but until then just add these methods the manual # sip way. c.find('iterator').addItem( etgtools.WigCode("""\ iterator& _next(); %MethodCode PyErr_Clear(); Py_BEGIN_ALLOW_THREADS sipRes = &sipCpp->operator++(); Py_END_ALLOW_THREADS if (PyErr_Occurred()) return 0; %End const wxGridBlockCoords& _get() const; %MethodCode PyErr_Clear(); Py_BEGIN_ALLOW_THREADS sipRes = new ::wxGridBlockCoords(sipCpp->operator*()); Py_END_ALLOW_THREADS if (PyErr_Occurred()) return 0; %End bool __eq__(const iterator& it) const; bool __ne__(const iterator& it) const; """)) #----------------------------------------------------------------- c = module.find('wxGridSizesInfo') c.find('m_customSizes').ignore( ) # TODO: Add support for wxUnsignedToIntHashMap?? #----------------------------------------------------------------- def fixRendererClass(name): klass = module.find(name) assert isinstance(klass, etgtools.ClassDef) tools.fixRefCountedClass(klass) tools.addAutoProperties(klass) methods = [ ('Clone', "virtual wxGridCellRenderer* Clone() const /Factory/;"), ('Draw', "virtual void Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, " " const wxRect& rect, int row, int col, bool isSelected);"), ('GetBestSize', "virtual wxSize GetBestSize(wxGrid& grid, wxGridCellAttr& attr, " " wxDC& dc, int row, int col);"), ] for method, code in methods: if not klass.findItem(method): klass.addItem(etgtools.WigCode(code)) c = module.find('wxGridCellRenderer') c.addPrivateCopyCtor() c.find('~wxGridCellRenderer').ignore(False) c.find('Clone').factory = True tools.fixRefCountedClass(c) for name in ITEMS: if 'Cell' in name and 'Renderer' in name: fixRendererClass(name) module.addPyCode( "PyGridCellRenderer = wx.deprecated(GridCellRenderer, 'Use GridCellRenderer instead.')" ) #----------------------------------------------------------------- c = module.find('wxGridActivationResult') c.ignore() # FIXME c.addPrivateAssignOp() c.instanceCode = 'sipCpp = new wxGridActivationResult::DoNothing();' c = module.find('wxGridActivationSource') c.ignore() # FIXME c.noDefCtor = True c.addPrivateAssignOp() #----------------------------------------------------------------- def fixEditorClass(name): klass = module.find(name) assert isinstance(klass, etgtools.ClassDef) tools.fixRefCountedClass(klass) tools.addAutoProperties(klass) methods = [ ('BeginEdit', "virtual void BeginEdit(int row, int col, wxGrid* grid);"), ('Clone', "virtual wxGridCellEditor* Clone() const /Factory/;"), ('Create', "virtual void Create(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler);" ), #('EndEdit', "virtual bool EndEdit(int row, int col, const wxGrid* grid, const wxString& oldval, wxString* newval);"), ('ApplyEdit', "virtual void ApplyEdit(int row, int col, wxGrid* grid);"), ('Reset', "virtual void Reset();"), ('GetValue', "virtual wxString GetValue() const;"), ] for method, code in methods: if not klass.findItem(method): klass.addItem(etgtools.WigCode(code)) # Fix up EndEdit so it returns newval on success or None on failure pureVirtual = False if klass.findItem('EndEdit'): klass.find('EndEdit').ignore() pureVirtual = True # The Python version of EndEdit has a different signature than the # C++ version, so we need to take care of mapping between them so the # C++ compiler still recognizes this as a match for the virtual # method in the base class. klass.addCppMethod( 'PyObject*', 'EndEdit', '(int row, int col, const wxGrid* grid, const wxString& oldval)', cppSignature= 'bool (int row, int col, const wxGrid* grid, const wxString& oldval, wxString* newval)', pyArgsString='(row, col, grid, oldval)', isVirtual=True, isPureVirtual=pureVirtual, doc="""\ End editing the cell. This function must check if the current value of the editing cell is valid and different from the original value in its string form. If not then simply return None. If it has changed then this method should save the new value so that ApplyEdit can apply it later and the string representation of the new value should be returned. Notice that this method shoiuld not modify the grid as the change could still be vetoed. """, # Code for Python --> C++ calls. Make it return newval or None. body="""\ bool rv; wxString newval; rv = self->EndEdit(row, col, grid, *oldval, &newval); if (rv) { return wx2PyString(newval); } else { Py_INCREF(Py_None); return Py_None; } """, # Code for C++ --> Python calls. This is used when a C++ method # call needs to be reflected to a call to the overridden Python # method, so we need to translate between the real C++ signature # and the Python signature. virtualCatcherCode="""\ // VirtualCatcherCode for wx.grid.GridCellEditor.EndEdit PyObject *result; result = sipCallMethod(0, sipMethod, "iiDN", row, col, const_cast<wxGrid *>(grid),sipType_wxGrid,NULL, new wxString(oldval),sipType_wxString,NULL); if (result == NULL) { if (PyErr_Occurred()) PyErr_Print(); sipRes = false; } else if (result == Py_None) { sipRes = false; } else { sipRes = true; *newval = Py2wxString(result); } Py_XDECREF(result); """ if pureVirtual else "", # only used with the base class ) c = module.find('wxGridCellEditor') c.addPrivateCopyCtor() c.find('~wxGridCellEditor').ignore(False) c.find('Clone').factory = True tools.fixRefCountedClass(c) c.find('TryActivate').ignore( ) # FIXME: remove this when the compilation issues with wxGridActivationResult is fixed c = module.find('wxGridCellActivatableEditor') c.ignore() # FIXME: see above c = module.find('wxGridCellChoiceEditor') c.find('wxGridCellChoiceEditor').findOverload('count').ignore() for name in ITEMS: if 'Cell' in name and 'Editor' in name and name != 'wxGridCellActivatableEditor': fixEditorClass(name) module.addPyCode( "PyGridCellEditor = wx.deprecated(GridCellEditor, 'Use GridCellEditor instead.')" ) #----------------------------------------------------------------- c = module.find('wxGridCellAttr') c.addPrivateCopyCtor() c.find('~wxGridCellAttr').ignore(False) c.find('Clone').factory = True tools.fixRefCountedClass(c) c.find('GetAlignment.hAlign').out = True c.find('GetAlignment.vAlign').out = True c.find('GetNonDefaultAlignment.hAlign').out = True c.find('GetNonDefaultAlignment.vAlign').out = True c.find('GetSize.num_rows').out = True c.find('GetSize.num_cols').out = True c.find('SetEditor.editor' ).transfer = True # these are probably redundant now... c.find('SetRenderer.renderer').transfer = True #----------------------------------------------------------------- module.find('wxGridCellRendererPtr').piIgnored = True module.find('wxGridCellEditorPtr').piIgnored = True module.find('wxGridCellAttrPtr').piIgnored = True #----------------------------------------------------------------- # The instanceCode attribute is code that is used to make a default # instance of the class. We can't create them using the same class in # this case because they are abstract. c = module.find('wxGridCornerHeaderRenderer') c.instanceCode = 'sipCpp = new wxGridCornerHeaderRendererDefault;' c = module.find('wxGridRowHeaderRenderer') c.instanceCode = 'sipCpp = new wxGridRowHeaderRendererDefault;' c = module.find('wxGridColumnHeaderRenderer') c.instanceCode = 'sipCpp = new wxGridColumnHeaderRendererDefault;' #----------------------------------------------------------------- c = module.find('wxGridCellAttrProvider') c.addPrivateCopyCtor() c.find('SetAttr.attr').transfer = True c.find('SetRowAttr.attr').transfer = True c.find('SetColAttr.attr').transfer = True module.addPyCode( "PyGridCellAttrProvider = wx.deprecated(GridCellAttrProvider, 'Use GridCellAttrProvider instead.')" ) #----------------------------------------------------------------- c = module.find('wxGridTableBase') c.addPrivateCopyCtor() c.find('SetAttr.attr').transfer = True c.find('SetRowAttr.attr').transfer = True c.find('SetColAttr.attr').transfer = True module.addPyCode( "PyGridTableBase = wx.deprecated(GridTableBase, 'Use GridTableBase instead.')" ) # Make the GetValue methods easier to use from Python. For example, # instead of needing to always return a string, the GetValue in the derived # class can return any type (as long as the renderer and editor knows how # to deal with it, and the value can be converted to a string for display). m = c.find('GetValue') m.type = 'PyObject*' m.cppSignature = 'wxString (int row, int col)' m.setCppCode("return wx2PyString(self->GetValue(row, col));") m.virtualCatcherCode = """\ // virtualCatcherCode for GridTableBase.GetValue PyObject *result = sipCallMethod(&sipIsErr, sipMethod, "ii", row, col); if (result == NULL) { if (PyErr_Occurred()) PyErr_Print(); sipRes = ""; } else if (result == Py_None) { sipRes = ""; } else { if (!PyBytes_Check(result) && !PyUnicode_Check(result)) { PyObject* old = result; result = PyObject_Str(result); Py_DECREF(old); } sipRes = Py2wxString(result); } Py_XDECREF(result); """ # SetValue is okay as-is... # Replace these virtuals in the base class with Python methods, they just # need to call GetValue or SetValue directly since they must already be # implemented in the derived Python class because they are pure virtual. c.addPyMethod('GetValueAsLong', '(self, row, col)', body="""\ val = self.GetValue(row, col) try: return int(val) except ValueError: return 0 """, docsIgnored=True) c.addPyMethod('GetValueAsDouble', '(self, row, col)', body="""\ val = self.GetValue(row, col) try: return float(val) except ValueError: return 0.0 """, docsIgnored=True) c.addPyMethod('GetValueAsBool', '(self, row, col)', body="""\ val = self.GetValue(row, col) try: return bool(val) except ValueError: return False """, docsIgnored=True) c.addPyMethod('SetValueAsLong', '(self, row, col, value)', body="self.SetValue(row, col, int(value))", docsIgnored=True) c.addPyMethod('SetValueAsDouble', '(self, row, col, value)', body="self.SetValue(row, col, float(value))", docsIgnored=True) c.addPyMethod('SetValueAsBool', '(self, row, col, value)', body="self.SetValue(row, col, bool(value))", docsIgnored=True) # Should we add support for using generic PyObjects in the *AsCustom # methods? I don't think it is necessary due to the GetValue # modifications above, so for now, at least, let.s just ignore them. c.find('GetValueAsCustom').ignore() c.find('SetValueAsCustom').ignore() #----------------------------------------------------------------- c = module.find('wxGridStringTable') c.addPrivateCopyCtor() #----------------------------------------------------------------- c = module.find('wxGridTableMessage') c.addPrivateCopyCtor() #----------------------------------------------------------------- c = module.find('wxGrid') tools.fixWindowClass(c, ignoreProtected=False) c.bases = ['wxScrolledCanvas'] c.find('GetColLabelAlignment.horiz').out = True c.find('GetColLabelAlignment.vert').out = True c.find('GetRowLabelAlignment.horiz').out = True c.find('GetRowLabelAlignment.vert').out = True c.find('GetCellAlignment.horiz').out = True c.find('GetCellAlignment.vert').out = True c.find('GetDefaultCellAlignment.horiz').out = True c.find('GetDefaultCellAlignment.vert').out = True c.find('RegisterDataType.renderer').transfer = True c.find('RegisterDataType.editor').transfer = True c.find('SetRowAttr.attr').transfer = True c.find('SetColAttr.attr').transfer = True c.find('SetCellEditor.editor').transfer = True c.find('SetCellRenderer.renderer').transfer = True # This overload is deprecated, so don't generate code for it. c.find('SetCellValue').findOverload('wxString &val').ignore() c.find('SetDefaultEditor.editor').transfer = True c.find('SetDefaultRenderer.renderer').transfer = True for n in [ 'GetColGridLinePen', 'GetDefaultGridLinePen', 'GetRowGridLinePen' ]: c.find(n).isVirtual = True # The SetTable method can optionally pass ownership of the table # object to the grid, so we need to optionally update the # ownership of the Python proxy object to match. c.find('SetTable').pyName = '_SetTable' c.addPyMethod( 'SetTable', '(self, table, takeOwnership=False, selmode=Grid.GridSelectCells)', piArgsString= '(self, table, takeOwnership=False, selmode=GridSelectCells)', doc="Set the Grid Table to be used by this grid.", body="""\ val = self._SetTable(table, takeOwnership, selmode) if takeOwnership: import wx.siplib wx.siplib.transferto(table, self) return val """) # SIP will normally try to add support for overriding this method since # it is inherited from super classes, but in this case we want it to be # ignored (because IRL it is private in one of the intermediate classes) # so we'll tell SIP that it is private here instead. c.addItem( etgtools.WigCode("""\ wxSize GetSizeAvailableForScrollTarget(const wxSize& size); """, protection='private')) # Add a simpler set of names for the wxGridSelectionModes enum c.addPyCode("""\ Grid.SelectCells = Grid.GridSelectCells Grid.SelectRows = Grid.GridSelectRows Grid.SelectColumns = Grid.GridSelectColumns Grid.SelectRowsOrColumns = Grid.GridSelectRowsOrColumns """) c.find('SetCellAlignment').findOverload('align').ignore() c.find('SetCellTextColour').overloads = [] c.find('GetGridWindowOffset').findOverload('int &x').ignore() # Custom code to deal with the wxGridBlockCoordsVector return type of these # methods. It's a wxVector, which we'll just convert to a list. # TODO: There are a few of these now to we ought to either wrap wxVector, or add # something in tweaker_tools to make adding code like this easier and more # automated. code = """\ wxPyThreadBlocker blocker; PyObject* result = PyList_New(0); wxGridBlockCoordsVector vector = self->{method}(); for (size_t idx=0; idx < vector.size(); idx++) {{ PyObject* obj; wxGridBlockCoords* item = new wxGridBlockCoords(vector[idx]); obj = wxPyConstructObject((void*)item, "wxGridBlockCoords", true); PyList_Append(result, obj); Py_DECREF(obj); }} return result; """ c.find('GetSelectedRowBlocks').type = 'PyObject*' c.find('GetSelectedRowBlocks').setCppCode( code.format(method='GetSelectedRowBlocks')) c.find('GetSelectedColBlocks').type = 'PyObject*' c.find('GetSelectedColBlocks').setCppCode( code.format(method='GetSelectedColBlocks')) #----------------------------------------------------------------- c = module.find('wxGridUpdateLocker') c.addPrivateCopyCtor() # context manager methods c.addPyMethod('__enter__', '(self)', 'return self') c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False') #----------------------------------------------------------------- for name in [ 'wxGridSizeEvent', 'wxGridRangeSelectEvent', 'wxGridEditorCreatedEvent', 'wxGridEvent' ]: c = module.find(name) tools.fixEventClass(c) module.addPyCode("""\ EVT_GRID_CELL_LEFT_CLICK = wx.PyEventBinder( wxEVT_GRID_CELL_LEFT_CLICK ) EVT_GRID_CELL_RIGHT_CLICK = wx.PyEventBinder( wxEVT_GRID_CELL_RIGHT_CLICK ) EVT_GRID_CELL_LEFT_DCLICK = wx.PyEventBinder( wxEVT_GRID_CELL_LEFT_DCLICK ) EVT_GRID_CELL_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_GRID_CELL_RIGHT_DCLICK ) EVT_GRID_LABEL_LEFT_CLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_LEFT_CLICK ) EVT_GRID_LABEL_RIGHT_CLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_RIGHT_CLICK ) EVT_GRID_LABEL_LEFT_DCLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_LEFT_DCLICK ) EVT_GRID_LABEL_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_RIGHT_DCLICK ) EVT_GRID_ROW_SIZE = wx.PyEventBinder( wxEVT_GRID_ROW_SIZE ) EVT_GRID_COL_SIZE = wx.PyEventBinder( wxEVT_GRID_COL_SIZE ) EVT_GRID_RANGE_SELECT = wx.PyEventBinder( wxEVT_GRID_RANGE_SELECT ) EVT_GRID_CELL_CHANGING = wx.PyEventBinder( wxEVT_GRID_CELL_CHANGING ) EVT_GRID_CELL_CHANGED = wx.PyEventBinder( wxEVT_GRID_CELL_CHANGED ) EVT_GRID_SELECT_CELL = wx.PyEventBinder( wxEVT_GRID_SELECT_CELL ) EVT_GRID_EDITOR_SHOWN = wx.PyEventBinder( wxEVT_GRID_EDITOR_SHOWN ) EVT_GRID_EDITOR_HIDDEN = wx.PyEventBinder( wxEVT_GRID_EDITOR_HIDDEN ) EVT_GRID_EDITOR_CREATED = wx.PyEventBinder( wxEVT_GRID_EDITOR_CREATED ) EVT_GRID_CELL_BEGIN_DRAG = wx.PyEventBinder( wxEVT_GRID_CELL_BEGIN_DRAG ) EVT_GRID_COL_MOVE = wx.PyEventBinder( wxEVT_GRID_COL_MOVE ) EVT_GRID_COL_SORT = wx.PyEventBinder( wxEVT_GRID_COL_SORT ) EVT_GRID_TABBING = wx.PyEventBinder( wxEVT_GRID_TABBING ) # The same as above but with the ability to specify an identifier EVT_GRID_CMD_CELL_LEFT_CLICK = wx.PyEventBinder( wxEVT_GRID_CELL_LEFT_CLICK, 1 ) EVT_GRID_CMD_CELL_RIGHT_CLICK = wx.PyEventBinder( wxEVT_GRID_CELL_RIGHT_CLICK, 1 ) EVT_GRID_CMD_CELL_LEFT_DCLICK = wx.PyEventBinder( wxEVT_GRID_CELL_LEFT_DCLICK, 1 ) EVT_GRID_CMD_CELL_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_GRID_CELL_RIGHT_DCLICK, 1 ) EVT_GRID_CMD_LABEL_LEFT_CLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_LEFT_CLICK, 1 ) EVT_GRID_CMD_LABEL_RIGHT_CLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_RIGHT_CLICK, 1 ) EVT_GRID_CMD_LABEL_LEFT_DCLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_LEFT_DCLICK, 1 ) EVT_GRID_CMD_LABEL_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_RIGHT_DCLICK, 1 ) EVT_GRID_CMD_ROW_SIZE = wx.PyEventBinder( wxEVT_GRID_ROW_SIZE, 1 ) EVT_GRID_CMD_COL_SIZE = wx.PyEventBinder( wxEVT_GRID_COL_SIZE, 1 ) EVT_GRID_CMD_RANGE_SELECT = wx.PyEventBinder( wxEVT_GRID_RANGE_SELECT, 1 ) EVT_GRID_CMD_CELL_CHANGING = wx.PyEventBinder( wxEVT_GRID_CELL_CHANGING, 1 ) EVT_GRID_CMD_CELL_CHANGED = wx.PyEventBinder( wxEVT_GRID_CELL_CHANGED, 1 ) EVT_GRID_CMD_SELECT_CELL = wx.PyEventBinder( wxEVT_GRID_SELECT_CELL, 1 ) EVT_GRID_CMD_EDITOR_SHOWN = wx.PyEventBinder( wxEVT_GRID_EDITOR_SHOWN, 1 ) EVT_GRID_CMD_EDITOR_HIDDEN = wx.PyEventBinder( wxEVT_GRID_EDITOR_HIDDEN, 1 ) EVT_GRID_CMD_EDITOR_CREATED = wx.PyEventBinder( wxEVT_GRID_EDITOR_CREATED, 1 ) EVT_GRID_CMD_CELL_BEGIN_DRAG = wx.PyEventBinder( wxEVT_GRID_CELL_BEGIN_DRAG, 1 ) EVT_GRID_CMD_COL_MOVE = wx.PyEventBinder( wxEVT_GRID_COL_MOVE, 1 ) EVT_GRID_CMD_COL_SORT = wx.PyEventBinder( wxEVT_GRID_COL_SORT, 1 ) EVT_GRID_CMD_TABBING = wx.PyEventBinder( wxEVT_GRID_TABBING, 1 ) """) #----------------------------------------------------------------- #----------------------------------------------------------------- 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) c.addCppMethod('int', '__nonzero__', '()', """\ return self->IsOk(); """) c.addCppMethod('bool', '__eq__', '(const wxTreeItemId* other)', """\ return *self == *other; """) c.addCppMethod('bool', '__neq__', '(const wxTreeItemId* other)', """\ return *self != *other; """) c.addPyMethod('__hash__', '(self)', """\ return hash(int(self.GetID())) """) 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) # 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('AssignImageList.imageList').transfer = True 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) c.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) #----------------------------------------------------------------- # 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, check4unittest=False) 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 <wx/textfile.h>") # tweaks for defs.h to help SIP understand the types better module.find('wxInt16').type = 'short' module.find('wxInt64').type = 'long long' module.find('wxUint64').type = 'unsigned long long' # See src/wacky_ints.sip module.find('wxIntPtr').ignore() module.find('wxUIntPtr').ignore() # Correct the types for these as their values are outside the range of int module.find('wxUINT32_MAX').type = 'unsigned long' module.find('wxINT64_MIN').type = 'long long' module.find('wxINT64_MAX').type = 'long long' module.find('wxUINT64_MAX').type = 'unsigned long long' # Generate the code for these differently because they need to be # forcibly mashed into an int in the C code module.find('wxCANCEL_DEFAULT').forcedInt = True module.find('wxVSCROLL').forcedInt = True module.find('wxWINDOW_STYLE_MASK').forcedInt = True module.find('wxInt8').pyInt = True module.find('wxUint8').pyInt = True module.find('wxByte').pyInt = True module.find('wxDELETE').ignore() module.find('wxDELETEA').ignore() module.find('wxSwap').ignore() module.find('wxVaCopy').ignore() # Add some typedefs for basic wx types and others so the backend # generator knows what they are td = module.find('wxUIntPtr') module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxUChar')) module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxChar')) module.insertItemAfter(td, etgtools.TypedefDef(type='long', name='time_t')) module.insertItemAfter( td, etgtools.TypedefDef(type='long long', name='wxFileOffset')) module.insertItemAfter( td, etgtools.TypedefDef(type='SIP_SSIZE_T', name='ssize_t')) module.insertItemAfter( td, etgtools.TypedefDef(type='unsigned char', name='byte', pyInt=True)) module.insertItemAfter( td, etgtools.TypedefDef(type='unsigned long', name='ulong')) # Forward declarations for classes that are referenced but not defined # yet. # # TODO: Remove these when the classes are added for real. # TODO: Add these classes for real :-) module.insertItem( 0, etgtools.WigCode("""\ // forward declarations class wxExecuteEnv; """)) # Add some code for getting the version numbers module.addCppCode(""" #include <wx/version.h> const int MAJOR_VERSION = wxMAJOR_VERSION; const int MINOR_VERSION = wxMINOR_VERSION; const int RELEASE_NUMBER = wxRELEASE_NUMBER; """) module.addItem( etgtools.WigCode(""" const int MAJOR_VERSION; const int MINOR_VERSION; const int RELEASE_NUMBER; """)) # TODO: these should be removed someday module.addPyCode("BG_STYLE_CUSTOM = BG_STYLE_PAINT") module.addPyCode("ADJUST_MINSIZE = 0") module.addPyCode("WS_EX_VALIDATE_RECURSIVELY = 0") #----------------------------------------------------------------- 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, check4unittest=False) etgtools.parseDoxyXML(module, ITEMS) #----------------------------------------------------------------- # Tweak the parsed meta objects in the module object as needed for # customizing the generated code and docstrings. module.find('wxCreateDynamicObject').ignore() #-------------------------------------------------- c = module.find('wxClassInfo') assert isinstance(c, etgtools.ClassDef) module.insertItemBefore( c, etgtools.TypedefDef(type='void*', name='wxObjectConstructorFn')) module.find('wxClassInfo').abstract = True module.find('wxClassInfo.wxClassInfo').ignore() #-------------------------------------------------- c = module.find('wxRefCounter') assert isinstance(c, etgtools.ClassDef) c.find('~wxRefCounter').ignore(False) c.addPrivateCopyCtor() tools.fixRefCountedClass(c) #-------------------------------------------------- c = module.find('wxObject') c.find('operator delete').ignore() c.find('operator new').ignore() c.find('IsKindOf').ignore() # EXPERIMENTAL: By turning off the virtualness of the wxObject dtor, and # since there are no other virtuals that we are exposing here, then all # classes that derive from wxObject that do not have any virtuals of # their own (or have the virtual flags turned off by the tweaker code) # can have simpler wrappers generated for them with no extra derived # class whose only purpose is to reflect calls to the virtual methods to # Python implementations. (And since the only virtual is the dtor then # that is of no real benefit to Python code since we're not overriding # the dtor anyhow.) In addition it appears so far that none of these # classes would ever need to have Python derived classes anyway. This # also makes it easier and less SIP-specific to add or replace ctors in # those classes with custom C++ code. (See wxFont and wxAcceleratorTable # for examples.) c.find('~wxObject').isVirtual = False c.find('GetClassInfo').isVirtual = False c.addCppMethod('const wxChar*', 'GetClassName', '()', body='return self->GetClassInfo()->GetClassName();', doc='Returns the class name of the C++ class using wxRTTI.') c.addCppMethod( 'void', 'Destroy', '()', body='delete self;', doc='Deletes the C++ object this Python object is a proxy for.', transferThis=True) # TODO: Check this tools.addSipConvertToSubClassCode(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, check4unittest=False) 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. # tweaks for defs.h to help SIP understand the types better module.find('wxInt16').type = 'short' module.find('wxInt64').type = 'long long' module.find('wxUint64').type = 'unsigned long long' # NOTE: this is better, but probably still not totally correct... if sys.maxsize > 2**32: module.find('wxIntPtr').type = 'long long' #'ssize_t' module.find('wxUIntPtr').type = 'unsigned long long' #'size_t' else: module.find('wxIntPtr').type = 'long' #'ssize_t' module.find('wxUIntPtr').type = 'unsigned long' #'size_t' module.find('wxInt8').pyInt = True module.find('wxUint8').pyInt = True module.find('wxByte').pyInt = True module.find('wxDELETE').ignore() module.find('wxDELETEA').ignore() module.find('wxSwap').ignore() module.find('wxVaCopy').ignore() # Add some typedefs for basic wx types and others so the backend # generator knows what they are td = module.find('wxUIntPtr') module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxUChar')) module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxChar')) module.insertItemAfter(td, etgtools.TypedefDef(type='unsigned long', name='size_t')) module.insertItemAfter(td, etgtools.TypedefDef(type='long', name='time_t')) module.insertItemAfter(td, etgtools.TypedefDef(type='long long', name='wxFileOffset')) module.insertItemAfter(td, etgtools.TypedefDef(type='SIP_SSIZE_T', name='ssize_t')) module.insertItemAfter(td, etgtools.TypedefDef(type='unsigned char', name='byte', pyInt=True)) # Forward declarations for classes that are referenced but not defined # yet. # # TODO: Remove these when the classes are added for real. # TODO: Add these classes for real :-) module.insertItem(0, etgtools.WigCode("""\ // forward declarations class wxPalette; class wxExecuteEnv; """)) # Add some code for getting the version numbers module.addCppCode(""" #include <wx/version.h> const int MAJOR_VERSION = wxMAJOR_VERSION; const int MINOR_VERSION = wxMINOR_VERSION; const int RELEASE_NUMBER = wxRELEASE_NUMBER; """) module.addItem(etgtools.WigCode(""" const int MAJOR_VERSION; const int MINOR_VERSION; const int RELEASE_NUMBER; """)) module.addPyCode("BG_STYLE_CUSTOM = BG_STYLE_PAINT") #----------------------------------------------------------------- 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)