Move wx.PyEvent and wx.PyCommandEvent to etg objects so the doc builder will see them.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@72867 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2012-11-03 01:22:55 +00:00
parent 999329d7ed
commit e38c8527e0
4 changed files with 258 additions and 208 deletions

View File

@@ -112,10 +112,6 @@ other dev stuff
created/used that should not be done before there is an application
object.
* Move PyEvent and PyCommandEvent classes to an etg script and build them
using extractor objects so they will be seen by the document generator and
others.
* Locate and/or add items for the various functions and things in Classic's
_functions.i module.

135
etg/pyevent.py Normal file
View File

@@ -0,0 +1,135 @@
#---------------------------------------------------------------------------
# Name: etg/pyevent.py
# Author: Robin Dunn
#
# Created: 02-Nov-2012
# Copyright: (c) 2012 by Total Control Software
# License: wxWindows License
#---------------------------------------------------------------------------
import etgtools
import etgtools.tweaker_tools as tools
from etgtools.extractors import ClassDef, MethodDef, ParamDef
PACKAGE = "wx"
MODULE = "_core"
NAME = "pyevent" # Base name of the file to generate to for this script
DOCSTRING = ""
# The classes and/or the basename of the Doxygen XML files to be processed by
# this script.
ITEMS = [ ]
#---------------------------------------------------------------------------
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.
cls = ClassDef(name='wxPyEvent', bases=['wxEvent'],
briefDoc="""\
wx.PyEvent can be used as a base class for implementing custom
event types in Python. You should derive from this class instead
of `wx.Event` because this class is Python-aware and is able to
transport its Python bits safely through the wxWidgets event
system and have them still be there when the event handler is
invoked. Note that since wx.PyEvent is taking care of preserving
the extra attributes that have been set then you do not need to
override the Clone method in your derived classes.
:see: `wx.PyCommandEvent`""",
items=[
MethodDef(name='wxPyEvent', isCtor=True, items=[
ParamDef(type='int', name='id', default='0'),
ParamDef(type='wxEventType', name='evenType', default='wxEVT_NULL'),
]),
MethodDef(name='__getattr__', type='PyObject*', items=[
ParamDef(type='PyObject*', name='name'),],
cppCode=("sipRes = sipCpp->__getattr__(name);", "sip")),
MethodDef(name='__delattr__', type='void', items=[
ParamDef(type='PyObject*', name='name'),],
cppCode=("sipCpp->__delattr__(name);", "sip")),
MethodDef(name='__setattr__', type='void', items=[
ParamDef(type='PyObject*', name='name'),
ParamDef(type='PyObject*', name='value'),],
cppCode=("sipCpp->__setattr__(name, value);", "sip")),
MethodDef(name='Clone', type='wxEvent*', isVirtual=True, isConst=True, factory=True),
MethodDef(name='_getAttrDict', type='PyObject*'),
])
module.addItem(cls)
cls.addCppCode("IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxEvent);")
cls.addHeaderCode('#include "pyevent.h"')
cls = ClassDef(name='wxPyCommandEvent', bases=['wxCommandEvent'],
briefDoc="""\
wx.PyCommandEvent can be used as a base class for implementing
custom event types in Python. You should derive from this class
instead of `wx.CommandEvent` because this class is Python-aware
and is able to transport its Python bits safely through the
wxWidgets event system and have them still be there when the
event handler is invoked. Note that since wx.PyCommandEvent is
taking care of preserving the extra attributes that have been set
then you do not need to override the Clone method in your
derived classes.
:see: `wx.PyEvent`""",
items=[
MethodDef(name='wxPyCommandEvent', isCtor=True, items=[
ParamDef(type='wxEventType', name='evenType', default='wxEVT_NULL'),
ParamDef(type='int', name='id', default='0'),
]),
MethodDef(name='__getattr__', type='PyObject*', items=[
ParamDef(type='PyObject*', name='name'),],
cppCode=("sipRes = sipCpp->__getattr__(name);", "sip")),
MethodDef(name='__delattr__', type='void', items=[
ParamDef(type='PyObject*', name='name'),],
cppCode=("sipCpp->__delattr__(name);", "sip")),
MethodDef(name='__setattr__', type='void', items=[
ParamDef(type='PyObject*', name='name'),
ParamDef(type='PyObject*', name='value'),],
cppCode=("sipCpp->__setattr__(name, value);", "sip")),
MethodDef(name='Clone', type='wxEvent*', isVirtual=True, isConst=True, factory=True),
MethodDef(name='_getAttrDict', type='PyObject*'),
])
module.addItem(cls)
cls.addCppCode("IMPLEMENT_DYNAMIC_CLASS(wxPyCommandEvent, wxCommandEvent);")
cls.addHeaderCode('#include "pyevent.h"')
# TODO: Temporary testing code, get rid of this later
module.addCppCode("""\
wxEvent* testCppClone(wxEvent& evt) {
return evt.Clone();
}""")
module.addItem(etgtools.WigCode("wxEvent* testCppClone(wxEvent& evt);"))
#-----------------------------------------------------------------
tools.doCommonTweaks(module)
tools.runGenerators(module)
#---------------------------------------------------------------------------
if __name__ == '__main__':
run()

123
src/pyevent.h Normal file
View File

@@ -0,0 +1,123 @@
//--------------------------------------------------------------------------
// Name: pyevent.h
// Purpose: A set of event classes that can be derived from in Python
// and that preserve their attributes when cloned.
//
// Author: Robin Dunn
//
// Created: 18-Dec-2010
// Copyright: (c) 2012 by Total Control Software
// Licence: wxWindows license
//--------------------------------------------------------------------------
#ifndef PYEVENT_H
#define PYEVENT_H
// The wxPyEvent and wxPyCommandEvent classes can be derived from in Python
// and passed through the event system without losing anything.
// This wxPyEvtDict class holds a Python dictionary object and is used to
// store any attributes that are set from Python code for the wx.PyEvent and
// wx.PyCommandEvent classes. This dictionary is used to make it easy to
// transport those attributes over to the clone when wx needs to make a copy
// of the event instance.
// NOTE: This class is intentionally not exposed to SIP as there is no
// need for it in Python code. Intead we just tell SIP that the __*attr__
// methods are in the event classes. (See wxPyEvent and wxPyCommandEvent
// below.)
class wxPyEvtDict
{
public:
wxPyEvtDict()
{
wxPyThreadBlocker blocker;
m_dict = PyDict_New();
}
wxPyEvtDict(const wxPyEvtDict& other)
{
wxPyThreadBlocker blocker;
m_dict = PyDict_Copy(other.m_dict);
}
~wxPyEvtDict()
{
wxPyThreadBlocker blocker;
Py_DECREF(m_dict);
m_dict = NULL;
}
PyObject* _getAttrDict()
{
wxPyThreadBlocker blocker;
Py_INCREF(m_dict);
return m_dict;
}
PyObject* __getattr__(PyObject* name)
{
PyObject* value = NULL;
wxPyThreadBlocker blocker;
if (PyDict_Contains(m_dict, name)) {
value = PyDict_GetItem(m_dict, name);
Py_INCREF(value);
}
else {
PyErr_SetObject(PyExc_AttributeError, name);
}
return value;
}
void __setattr__(PyObject* name, PyObject* value)
{
wxPyThreadBlocker blocker;
PyDict_SetItem(m_dict, name, value);
}
void __delattr__(PyObject* name)
{
wxPyThreadBlocker blocker;
if (PyDict_Contains(m_dict, name))
PyDict_DelItem(m_dict, name);
else
PyErr_SetObject(PyExc_AttributeError, name);
}
protected:
PyObject* m_dict;
};
//--------------------------------------------------------------------------
class wxPyEvent : public wxEvent, public wxPyEvtDict
{
DECLARE_DYNAMIC_CLASS(wxPyEvent)
public:
wxPyEvent(int id=0, wxEventType eventType = wxEVT_NULL)
: wxEvent(id, eventType) {}
virtual wxEvent* Clone() const { return new wxPyEvent(*this); }
};
//--------------------------------------------------------------------------
class wxPyCommandEvent : public wxCommandEvent, public wxPyEvtDict
{
DECLARE_DYNAMIC_CLASS(wxPyCommandEvent)
public:
wxPyCommandEvent(wxEventType eventType = wxEVT_NULL, int id=0)
: wxCommandEvent(eventType, id) {}
virtual wxEvent* Clone() const { return new wxPyCommandEvent(*this); }
};
//--------------------------------------------------------------------------
#endif

View File

@@ -1,204 +0,0 @@
//--------------------------------------------------------------------------
// Name: pyevent.sip
// Purpose: A set of event classes that can be derived from in Python
// and that preserve their attributes when cloned.
//
// Author: Robin Dunn
//
// Created: 18-Dec-2010
// Copyright: (c) 2011 by Total Control Software
// Licence: wxWindows license
//--------------------------------------------------------------------------
// The wxPyEvent and wxPyCommandEvent classes can be derived from in Python
// and passed through the event system without losing anything.
%ModuleHeaderCode
// This class holds a Python dictionary object and is used to store any
// attributes that are set from Python code for the wx.PyEvent and
// wx.PyCommandEvent classes. This dictionary is used to make it easy to
// transport those attributes over to the clone when wx needs to make a copy
// of the event instance.
// NOTE: This class is intentionally not exposed to SIP as there is no
// need for it in Python code. Intead we just tell SIP that the __*attr__
// methods are in the event classes. (See wxPyEvent and wxPyCommandEvent
// below.)
class wxPyEvtDict
{
public:
wxPyEvtDict()
{
wxPyBLOCK_THREADS(m_dict = PyDict_New());
}
wxPyEvtDict(const wxPyEvtDict& other)
{
wxPyBLOCK_THREADS(m_dict = PyDict_Copy(other.m_dict));
}
~wxPyEvtDict()
{
wxPyThreadBlocker blocker;
Py_DECREF(m_dict);
m_dict = NULL;
}
PyObject* _getAttrDict()
{
wxPyBLOCK_THREADS( Py_INCREF(m_dict) );
return m_dict;
}
PyObject* __getattr__(PyObject* name)
{
PyObject* value = NULL;
wxPyThreadBlocker blocker;
if (PyDict_Contains(m_dict, name)) {
value = PyDict_GetItem(m_dict, name);
Py_INCREF(value);
}
else {
PyErr_SetObject(PyExc_AttributeError, name);
}
return value;
}
void __setattr__(PyObject* name, PyObject* value)
{
wxPyThreadBlocker blocker;
PyDict_SetItem(m_dict, name, value);
}
void __delattr__(PyObject* name)
{
wxPyThreadBlocker blocker;
if (PyDict_Contains(m_dict, name))
PyDict_DelItem(m_dict, name);
else
PyErr_SetObject(PyExc_AttributeError, name);
}
protected:
PyObject* m_dict;
};
%End
//---------------------------------------------------------------------------
// TODO: Move these classes to an etg script and build using extractor
// objects so they will be seen by the document generator and others.
class wxPyEvent : wxEvent
{
%Docstring
wx.PyEvent can be used as a base class for implementing custom event types
in Python. You should derive from this class instead of `wx.Event` because
this class is Python-aware and is able to transport its Python bits safely
through the wxWidgets event system and have them still be there when the
event handler is invoked. Note that since wx.PyEvent is taking care of
preserving the extra attributes that have been set then you do not need to
implement the Clone method in your derived classes.
:see: `wx.PyCommandEvent`
%End
// first declare the C++ version of the class
%TypeCode
class wxPyEvent : public wxEvent, public wxPyEvtDict
{
DECLARE_DYNAMIC_CLASS(wxPyEvent)
public:
wxPyEvent(int id=0, wxEventType eventType = wxEVT_NULL)
: wxEvent(id, eventType) {}
virtual wxEvent* Clone() const { return new wxPyEvent(*this); }
};
IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxEvent);
%End
public:
wxPyEvent(int id=0, wxEventType eventType = wxEVT_NULL );
virtual wxEvent* Clone() const /Factory/;
PyObject* _getAttrDict();
PyObject* __getattr__(PyObject* name);
%MethodCode
sipRes = sipCpp->__getattr__(name);
%End
void __setattr__(PyObject* name, PyObject* value);
%MethodCode
sipCpp->__setattr__(name, value);
%End
void __delattr__(PyObject* name);
%MethodCode
sipCpp->__delattr__(name);
%End
};
class wxPyCommandEvent : wxCommandEvent
{
%Docstring
wx.PyCommandEvent can be used as a base class for implementing custom event types
in Python. You should derive from this class instead of `wx.CommandEvent` because
this class is Python-aware and is able to transport its Python bits safely
through the wxWidgets event system and have them still be there when the
event handler is invoked. Note that since wx.PyCommandEvent is taking care of
preserving the extra attributes that have been set then you do not need to
implement the Clone method in your derived classes.
:see: `wx.PyEvent`
%End
// first declare the C++ version of the class
%TypeCode
class wxPyCommandEvent : public wxCommandEvent, public wxPyEvtDict
{
DECLARE_DYNAMIC_CLASS(wxPyCommandEvent)
public:
wxPyCommandEvent(wxEventType eventType = wxEVT_NULL, int id=0)
: wxCommandEvent(eventType, id) {}
virtual wxEvent* Clone() const { return new wxPyCommandEvent(*this); }
};
IMPLEMENT_DYNAMIC_CLASS(wxPyCommandEvent, wxCommandEvent);
%End
public:
wxPyCommandEvent(wxEventType eventType = wxEVT_NULL, int id=0);
virtual wxEvent* Clone() const /Factory/;
PyObject* _getAttrDict();
PyObject* __getattr__(PyObject* name);
%MethodCode
sipRes = sipCpp->__getattr__(name);
%End
void __setattr__(PyObject* name, PyObject* value);
%MethodCode
sipCpp->__setattr__(name, value);
%End
void __delattr__(PyObject* name);
%MethodCode
sipCpp->__delattr__(name);
%End
};
// TODO: Temporary testing code, get rid of this later
%ModuleCode
wxEvent* testCppClone(wxEvent& evt)
{
return evt.Clone();
}
%End
wxEvent* testCppClone(wxEvent& evt);