mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-05 03:20:08 +01:00
A boatload of changes and additions, all my Phoenix work for the past few days. Lots of lower level classes are wrapped, wxApp is working up through OnInit, plus there's a good start on some unit tests.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@66272 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -51,7 +51,7 @@ class Configuration(object):
|
||||
|
||||
SIPOPTS = ' '.join(['-k', # turn on keyword args support
|
||||
'-o', # turn on auto-docstrings
|
||||
'-e', # turn on exceptions support
|
||||
#'-e', # turn on exceptions support
|
||||
'-T', # turn off writing the timestamp to the generated files
|
||||
#'-g', # always release and reaquire the GIL
|
||||
#'-r', # turn on function call tracing
|
||||
@@ -96,7 +96,7 @@ class Configuration(object):
|
||||
NO_SCRIPTS = False
|
||||
# Don't install the tools/script files
|
||||
|
||||
PKGDIR = 'wx'
|
||||
PKGDIR = 'wxPhoenix'
|
||||
# The name of the top-level package
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
@@ -145,8 +145,10 @@ class Configuration(object):
|
||||
self.WXDIR = '..' # assumes wxPython is subdir
|
||||
msg("WARNING: WXWIN not set in environment. Assuming '%s'" % self.WXDIR)
|
||||
|
||||
self.includes = ['sip/siplib'] # to get our version of sip.h
|
||||
|
||||
self.includes = ['sip/siplib', # to get our version of sip.h
|
||||
'src', # for any hand-written headers
|
||||
]
|
||||
|
||||
#---------------------------------------
|
||||
# MSW specific settings
|
||||
if os.name == 'nt' and self.COMPILER == 'msvc':
|
||||
@@ -512,10 +514,12 @@ def msg(text):
|
||||
if not runSilently:
|
||||
print text
|
||||
|
||||
|
||||
def opj(*args):
|
||||
path = os.path.join(*args)
|
||||
return os.path.normpath(path)
|
||||
|
||||
|
||||
def posixjoin(a, *p):
|
||||
"""Join two or more pathname components, inserting sep as needed"""
|
||||
path = a
|
||||
@@ -527,3 +531,20 @@ def posixjoin(a, *p):
|
||||
else:
|
||||
path = path + '/' + b
|
||||
return path
|
||||
|
||||
|
||||
def loadETG(name):
|
||||
"""
|
||||
Execute an ETG script so we can load a namespace with its contents (such
|
||||
as a list of dependencies, etc.) for use by setup.py
|
||||
"""
|
||||
class _Namespace(object):
|
||||
def __init__(self):
|
||||
self.__dict__['__name__'] = 'namespace'
|
||||
def nsdict(self):
|
||||
return self.__dict__
|
||||
|
||||
ns = _Namespace()
|
||||
execfile(name, ns.nsdict())
|
||||
return ns
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ import distutils.command.install
|
||||
import distutils.command.install_data
|
||||
import distutils.command.install_headers
|
||||
import distutils.command.clean
|
||||
from distutils.dep_util import newer
|
||||
from distutils.dep_util import newer, newer_group
|
||||
|
||||
from config import Config, posixjoin
|
||||
from config import Config, posixjoin, loadETG
|
||||
|
||||
|
||||
|
||||
@@ -361,7 +361,11 @@ class etgsip_build_ext(build_ext):
|
||||
for etg in etg_sources:
|
||||
sipfile = self.etg2sip(etg)
|
||||
|
||||
if newer(etg, sipfile):
|
||||
deps = [etg]
|
||||
ns = loadETG(etg)
|
||||
if hasattr(ns, 'OTHERDEPS'):
|
||||
deps += ns.OTHERDEPS
|
||||
if newer_group(deps, sipfile):
|
||||
cmd = [sys.executable, etg, '--sip']
|
||||
#if cfg.verbose:
|
||||
# cmd.append('--verbose')
|
||||
|
||||
291
etg/_core.py
291
etg/_core.py
@@ -1,5 +1,5 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: _core.py
|
||||
# Name: etg/_core.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 8-Nove-2010
|
||||
@@ -7,88 +7,245 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
PACKAGE = "wx"
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wxPhoenix" # This is just temporary, rename to 'wx' later.
|
||||
MODULE = "_core"
|
||||
NAME = "_core" # 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 = [
|
||||
'defs_8h.xml'
|
||||
]
|
||||
ITEMS = [ ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
# The list of other ETG scripts and back-end generator modules that are
|
||||
# included as part of this module. These items are in their own etg scripts
|
||||
# for easier maintainability, but their class and function definitions are
|
||||
# intended to be part of this module, not their own module. This also makes it
|
||||
# easier to promote one of these to module status later if desired, simply
|
||||
# remove it from this list of Includes, and change the MODULE value in the
|
||||
# promoted script to be the same as its NAME.
|
||||
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, ITEMS)
|
||||
INCLUDES = [ 'defs',
|
||||
'wxpy_utils',
|
||||
'string',
|
||||
'clntdata',
|
||||
'windowid',
|
||||
'platinfo',
|
||||
'display',
|
||||
'vidmode',
|
||||
'intl',
|
||||
|
||||
'gdiobj',
|
||||
'font',
|
||||
|
||||
'gdicmn',
|
||||
'geometry',
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for customizing
|
||||
# the generated code and docstrings.
|
||||
'object',
|
||||
'colour',
|
||||
'tracker',
|
||||
'kbdstate',
|
||||
'mousestate',
|
||||
'event',
|
||||
|
||||
'evtloop',
|
||||
'apptrait',
|
||||
'app',
|
||||
]
|
||||
|
||||
module.addHeaderCode('#include <wx/wx.h>')
|
||||
|
||||
|
||||
# These items are in their own etg scripts for easier maintainability,
|
||||
# but their class and function definitions are intended to be part of
|
||||
# this module, not their own module. This also makes it easier to
|
||||
# promote one of these to module status later if desired, simply
|
||||
# remove it fron this list of Includes, and change the MODULE value in
|
||||
# the promoted script to be the same as its NAME.
|
||||
|
||||
module.addInclude(['string',
|
||||
'clntdata',
|
||||
'windowid',
|
||||
'object',
|
||||
|
||||
'tracker',
|
||||
'kbdstate',
|
||||
'mousestate',
|
||||
'event',
|
||||
|
||||
'gdicmn',
|
||||
'geometry',
|
||||
|
||||
])
|
||||
|
||||
|
||||
# tweaks for defs.h
|
||||
module.find('wxInt16').type = 'short'
|
||||
module.find('wxInt64').type = 'long long'
|
||||
module.find('wxUint64').type = 'unsigned long long'
|
||||
module.find('wxIntPtr').type = 'long' #'ssize_t'
|
||||
module.find('wxUIntPtr').type = 'unsigned long' #'size_t'
|
||||
|
||||
module.find('wxDELETE').ignore()
|
||||
module.find('wxDELETEA').ignore()
|
||||
module.find('wxSwap').ignore()
|
||||
module.find('wxVaCopy').ignore()
|
||||
|
||||
# add some typedefs for wxChar, wxUChar
|
||||
td = module.find('wxUIntPtr')
|
||||
module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxUChar'))
|
||||
module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxChar'))
|
||||
|
||||
# Separate the list into those that are generated from ETG scripts and the
|
||||
# rest. These lists can be used from setup.py for a list of sources and a list
|
||||
# of additional dependencies when building this extension module
|
||||
ETGFILES = ['etg/%s.py' % NAME] + tools.getEtgFiles(INCLUDES)
|
||||
DEPENDS = tools.getNonEtgFiles(INCLUDES)
|
||||
OTHERDEPS = [ 'src/core_ex.py' ]
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
def run():
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, ITEMS)
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for
|
||||
# customizing the generated code and docstrings.
|
||||
|
||||
module.addHeaderCode("""\
|
||||
#if defined(__APPLE__)
|
||||
// When it's possible that we're building universal binaries with both
|
||||
// 32-bit and 64-bit architectures then these need to be undefed because
|
||||
// otherwise the values set by configure could conflict with those set
|
||||
// based on runtime flags in Python's headers. We also do something
|
||||
// similar in wx/platform.h so it's okay to undef them now because they
|
||||
// will be defined again soon.
|
||||
#undef SIZEOF_VOID_P
|
||||
#undef SIZEOF_LONG
|
||||
#undef SIZEOF_SIZE_T
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
// Turn off the warning about converting string literals to char*
|
||||
// TODO: fix these the right way...
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4190)
|
||||
#endif
|
||||
|
||||
#include <wx/wx.h>
|
||||
""")
|
||||
|
||||
module.addPyCode("""\
|
||||
# A little trick to make 'wx' be a reference to this module so wx.Names can
|
||||
# be used in the python code here.
|
||||
import sys as _sys
|
||||
wx = _sys.modules[__name__]
|
||||
""", order=10)
|
||||
module.includePyCode('src/core_ex.py')
|
||||
|
||||
module.addInclude(INCLUDES)
|
||||
|
||||
# This code is inserted into the module initialization function
|
||||
module.addPostInitializerCode("""
|
||||
wxPyCoreModuleInject(sipModuleDict);
|
||||
""")
|
||||
# Here is the function it calls
|
||||
module.addCppCode(wxPyCoreModuleInject)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
wxPyPreInit = """
|
||||
void wxPyPreInit(PyObject* moduleDict)
|
||||
{
|
||||
//#ifdef ISOLATION_AWARE_ENABLED
|
||||
// wxPySetActivationContext();
|
||||
//#endif
|
||||
//#ifdef __WXMSW__
|
||||
//// wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF
|
||||
//// | _CRTDBG_CHECK_ALWAYS_DF
|
||||
//// | _CRTDBG_DELAY_FREE_MEM_DF
|
||||
//// );
|
||||
//#endif
|
||||
//
|
||||
//#ifdef WXP_WITH_THREAD
|
||||
//#if wxPyUSE_GIL_STATE
|
||||
// PyEval_InitThreads();
|
||||
//#else
|
||||
// PyEval_InitThreads();
|
||||
// wxPyTStates = new wxPyThreadStateArray;
|
||||
// wxPyTMutex = new wxMutex;
|
||||
//
|
||||
// // Save the current (main) thread state in our array
|
||||
// PyThreadState* tstate = wxPyBeginAllowThreads();
|
||||
// wxPyEndAllowThreads(tstate);
|
||||
//#endif
|
||||
//#endif
|
||||
|
||||
// Ensure that the build options in the DLL (or whatever) match this build
|
||||
wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "wxPython");
|
||||
|
||||
wxInitAllImageHandlers();
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
wxPyCoreModuleInject = """
|
||||
void wxPyCoreModuleInject(PyObject* moduleDict)
|
||||
{
|
||||
// // Create an exception object to use for wxASSERTions
|
||||
// wxPyAssertionError = PyErr_NewException("wx._core.PyAssertionError",
|
||||
// PyExc_AssertionError, NULL);
|
||||
// PyDict_SetItemString(moduleDict, "PyAssertionError", wxPyAssertionError);
|
||||
//
|
||||
// // Create an exception object to use when the app object hasn't been created yet
|
||||
// wxPyNoAppError = PyErr_NewException("wx._core.PyNoAppError",
|
||||
// PyExc_RuntimeError, NULL);
|
||||
// PyDict_SetItemString(moduleDict, "PyNoAppError", wxPyNoAppError);
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#define wxPort "__WXGTK__"
|
||||
#define wxPortName "wxGTK"
|
||||
#endif
|
||||
#ifdef __WXMSW__
|
||||
#define wxPort "__WXMSW__"
|
||||
#define wxPortName "wxMSW"
|
||||
#endif
|
||||
#ifdef __WXMAC__
|
||||
#define wxPort "__WXMAC__"
|
||||
#define wxPortName "wxMac"
|
||||
#endif
|
||||
|
||||
PyDict_SetItemString(moduleDict, "Port", PyString_FromString(wxPort));
|
||||
|
||||
// Make a tuple of strings that gives more info about the platform and build.
|
||||
PyObject* PortInfo = PyList_New(0);
|
||||
PyObject* obj;
|
||||
|
||||
#define _AddInfoString(st) \
|
||||
obj = PyString_FromString(st); \
|
||||
PyList_Append(PortInfo, obj); \
|
||||
Py_DECREF(obj)
|
||||
|
||||
_AddInfoString(wxPort);
|
||||
_AddInfoString(wxPortName);
|
||||
#if wxUSE_UNICODE
|
||||
_AddInfoString("unicode");
|
||||
#if wxUSE_UNICODE_WCHAR
|
||||
_AddInfoString("unicode-wchar");
|
||||
#else
|
||||
_AddInfoString("unicode-utf8");
|
||||
#endif
|
||||
#else
|
||||
_AddInfoString("ansi");
|
||||
#endif
|
||||
|
||||
#ifdef __WXOSX__
|
||||
_AddInfoString("wxOSX");
|
||||
#endif
|
||||
#ifdef __WXOSX_CARBON__
|
||||
_AddInfoString("wxOSX-carbon");
|
||||
#endif
|
||||
#ifdef __WXOSX_COCOA__
|
||||
_AddInfoString("wxOSX-cocoa");
|
||||
#endif
|
||||
#ifdef __WXGTK__
|
||||
#ifdef __WXGTK20__
|
||||
_AddInfoString("gtk2");
|
||||
#else
|
||||
_AddInfoString("gtk1");
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __WXDEBUG__
|
||||
_AddInfoString("wx-assertions-on");
|
||||
#else
|
||||
_AddInfoString("wx-assertions-off");
|
||||
#endif
|
||||
#undef _AddInfoString
|
||||
|
||||
PyObject* PortInfoTuple = PyList_AsTuple(PortInfo);
|
||||
Py_DECREF(PortInfo);
|
||||
PyDict_SetItemString(moduleDict, "PortInfo", PortInfoTuple);
|
||||
}
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
158
etg/app.py
Normal file
158
etg/app.py
Normal file
@@ -0,0 +1,158 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/app.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created:
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "app" # 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 = [ 'wxAppConsole',
|
||||
'wxApp',
|
||||
]
|
||||
|
||||
OTHERDEPS = [ 'src/app_ex.py', # Some extra app-related Python code
|
||||
'src/app_ex.cpp', # and some C++ code too
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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('wxAppConsole')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
|
||||
# There's no need for the command line stuff as Python has its own ways to
|
||||
# deal with that
|
||||
c.find('argc').ignore()
|
||||
c.find('argv').ignore()
|
||||
c.find('OnCmdLineError').ignore()
|
||||
c.find('OnCmdLineHelp').ignore()
|
||||
c.find('OnCmdLineParsed').ignore()
|
||||
c.find('OnInitCmdLine').ignore()
|
||||
|
||||
c.find('HandleEvent').ignore()
|
||||
|
||||
c.addProperty('AppDisplayName GetAppDisplayName SetAppDisplayName')
|
||||
c.addProperty('AppName GetAppName SetAppName')
|
||||
c.addProperty('ClassName GetClassName SetClassName')
|
||||
c.addProperty('VendorDisplayName GetVendorDisplayName SetVendorDisplayName')
|
||||
c.addProperty('VendorName GetVendorName SetVendorName')
|
||||
|
||||
|
||||
c = module.find('wxApp')
|
||||
# Add a new C++ wxPyApp class that adds empty Mac* methods for other
|
||||
# platforms, and other goodies, then change the c.name so SIP will
|
||||
# generate code wrapping this class as if it was the wxApp class seen in
|
||||
# the DoxyXML.
|
||||
##c.addCppCode(wxPyApp)
|
||||
c.insertCppCode('src/app_ex.cpp')
|
||||
|
||||
for item in c.allItems(): # change the class name, ctors and dtor names
|
||||
if item.name == 'wxApp':
|
||||
item.name = 'wxPyApp'
|
||||
if item.name == '~wxApp':
|
||||
item.name = '~wxPyApp'
|
||||
|
||||
c.find('ProcessMessage').ignore()
|
||||
|
||||
c.addProperty('DisplayMode GetDisplayMode SetDisplayMode')
|
||||
c.addProperty('ExitOnFrameDelete GetExitOnFrameDelete SetExitOnFrameDelete')
|
||||
c.addProperty('LayoutDirection GetLayoutDirection')
|
||||
c.addProperty('UseBestVisual GetUseBestVisual SetUseBestVisual')
|
||||
c.addProperty('TopWindow GetTopWindow SetTopWindow')
|
||||
|
||||
|
||||
c.addCppMethod('void', 'MacHideApp', '()',
|
||||
doc="Hide all application windows just as the user can do with the\nsystem Hide command. Mac only.",
|
||||
body="""\
|
||||
#ifdef __WXMAC__
|
||||
sipCpp->MacHideApp();
|
||||
#endif
|
||||
""")
|
||||
|
||||
# Methods we implement in wxPyApp beyond what are in wxApp
|
||||
c.addItem(etgtools.WigCode("""\
|
||||
wxAppAssertMode GetAssertMode();
|
||||
void SetAssertMode(wxAppAssertMode mode);
|
||||
void _BootstrapApp();
|
||||
virtual void OnPreInit();
|
||||
virtual bool OnInit();
|
||||
static bool IsDisplayAvailable();
|
||||
"""))
|
||||
|
||||
appHeaderCode = """\
|
||||
enum wxAppAssertMode{
|
||||
wxPYAPP_ASSERT_SUPPRESS = 1,
|
||||
wxPYAPP_ASSERT_EXCEPTION = 2,
|
||||
wxPYAPP_ASSERT_DIALOG = 4,
|
||||
wxPYAPP_ASSERT_LOG = 8
|
||||
};
|
||||
"""
|
||||
# Add it to both the header and the generator files
|
||||
module.insertItemBefore(c, etgtools.WigCode(appHeaderCode))
|
||||
module.addHeaderCode(appHeaderCode)
|
||||
module.addHeaderCode("""\
|
||||
class wxPyApp;
|
||||
wxPyApp* wxGetApp();
|
||||
""")
|
||||
module.insertItemAfter(c, etgtools.WigCode("""\
|
||||
wxPyApp* wxGetApp();
|
||||
"""))
|
||||
|
||||
|
||||
# This includes Python code for the on-demand output window, the Python
|
||||
# derived wx.App class, etc.
|
||||
module.includePyCode('src/app_ex.py')
|
||||
|
||||
|
||||
module.find('wxTheApp').ignore()
|
||||
module.find('wxGetApp').ignore()
|
||||
module.find('wxInitialize').ignore()
|
||||
module.find('wxUninitialize').ignore()
|
||||
|
||||
for item in module.allItems():
|
||||
if item.name == 'wxEntry':
|
||||
item.ignore()
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
67
etg/apptrait.py
Normal file
67
etg/apptrait.py
Normal file
@@ -0,0 +1,67 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/apptrait.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 22-Nov-2010
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "apptrait" # 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 = [ 'wxAppTraits' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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('wxAppTraits')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
c.abstract = True
|
||||
|
||||
|
||||
# TODO: Enable these as their return types are added
|
||||
for name in [ 'CreateConfig',
|
||||
'CreateEventLoop',
|
||||
'CreateFontMapper',
|
||||
'CreateLogTarget',
|
||||
'CreateMessageOutput',
|
||||
'CreateRenderer',
|
||||
'GetStandardPaths' ]:
|
||||
c.find(name).ignore()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
298
etg/colour.py
Normal file
298
etg/colour.py
Normal file
@@ -0,0 +1,298 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etc/colour.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 19-Nov-2010
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "colour" # 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 = [ 'wxColour' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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.
|
||||
|
||||
|
||||
# Add a ctor/factory for the Mac that can use the theme brush
|
||||
module.addCppCode("""\
|
||||
#ifdef __WXMAC__
|
||||
#include <wx/osx/carbon/private.h>
|
||||
#endif
|
||||
""")
|
||||
|
||||
module.addCppFunction('wxColour', 'MacThemeColour', '(int themeBrushID)', """\
|
||||
#ifdef __WXMAC__
|
||||
sipRes = new wxColour(wxMacCreateCGColorFromHITheme(themeBrushID));
|
||||
#else
|
||||
wxPyRaiseNotImplemented();
|
||||
sipIsErr = 1;
|
||||
sipRes = NULL;
|
||||
#endif
|
||||
""", factory=True)
|
||||
|
||||
# Change this macro into a value so we wont have problems when SIP takes its
|
||||
# address
|
||||
module.addCppCode("""\
|
||||
#undef wxTransparentColour
|
||||
wxColour wxTransparentColour(0, 0, 0, wxALPHA_TRANSPARENT);
|
||||
""")
|
||||
|
||||
|
||||
module.find('wxFromString').ignore()
|
||||
module.find('wxToString').ignore()
|
||||
|
||||
# TODO: fix this?
|
||||
for name in [ 'wxBLACK',
|
||||
'wxBLUE',
|
||||
'wxCYAN',
|
||||
'wxGREEN',
|
||||
'wxYELLOW',
|
||||
'wxLIGHT_GREY',
|
||||
'wxRED',
|
||||
'wxWHITE',
|
||||
]:
|
||||
module.find(name).ignore()
|
||||
|
||||
module.find('wxALPHA_TRANSPARENT').type = 'const int'
|
||||
module.find('wxALPHA_OPAQUE').type = 'const int'
|
||||
|
||||
|
||||
|
||||
c = module.find('wxColour')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
tools.removeVirtuals(c)
|
||||
|
||||
# Hide the string ctor so our typemap will be invoked for the copy ctor instead.
|
||||
c.find('wxColour').findOverload('wxString').ignore()
|
||||
|
||||
c.addProperty('Pixel GetPixel')
|
||||
c.addProperty('RGB GetRGB SetRGB')
|
||||
c.addProperty('RGBA GetRGBA SetRGBA')
|
||||
c.addProperty('red Red')
|
||||
c.addProperty('green Green')
|
||||
c.addProperty('blue Blue')
|
||||
c.addProperty('alpha Alpha')
|
||||
|
||||
c.find('GetPixel').ignore() # We need to add a typcast
|
||||
c.addCppMethod('wxIntPtr', 'GetPixel', '()', """\
|
||||
sipRes = (wxIntPtr)sipCpp->GetPixel();
|
||||
""")
|
||||
|
||||
# Set a flag on the return value and parameter types that are 'unsigned char'
|
||||
# such that they will be treated as an integer instead of a string.
|
||||
for item in c.allItems():
|
||||
if hasattr(item, 'type') and item.type == 'unsigned char':
|
||||
item.pyInt = True
|
||||
|
||||
|
||||
c.find('ChangeLightness.r').inOut = True
|
||||
c.find('ChangeLightness.g').inOut = True
|
||||
c.find('ChangeLightness.b').inOut = True
|
||||
|
||||
c.find('MakeDisabled.r').inOut = True
|
||||
c.find('MakeDisabled.g').inOut = True
|
||||
c.find('MakeDisabled.b').inOut = True
|
||||
|
||||
c.find('MakeGrey.r').inOut = True
|
||||
c.find('MakeGrey.g').inOut = True
|
||||
c.find('MakeGrey.b').inOut = True
|
||||
c.find('MakeGrey').findOverload('double').find('r').inOut = True
|
||||
c.find('MakeGrey').findOverload('double').find('g').inOut = True
|
||||
c.find('MakeGrey').findOverload('double').find('b').inOut = True
|
||||
|
||||
c.find('MakeMono.r').out = True
|
||||
c.find('MakeMono.g').out = True
|
||||
c.find('MakeMono.b').out = True
|
||||
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '(bool includeAlpha=true)', """\
|
||||
int red = -1;
|
||||
int green = -1;
|
||||
int blue = -1;
|
||||
int alpha = wxALPHA_OPAQUE;
|
||||
if (sipCpp->IsOk()) {
|
||||
red = sipCpp->Red();
|
||||
green = sipCpp->Green();
|
||||
blue = sipCpp->Blue();
|
||||
alpha = sipCpp->Alpha();
|
||||
}
|
||||
if (includeAlpha)
|
||||
sipRes = sipBuildResult(&sipIsErr, "(iiii)", red, green, blue, alpha);
|
||||
else
|
||||
sipRes = sipBuildResult(&sipIsErr, "(iii)", red, green, blue);
|
||||
""", briefDoc="""\
|
||||
Get(includeAlpha=Valse) -> (r,g,b) or (r,g,b,a)\n
|
||||
Returns the RGB intensity values as a tuple, optionally the alpha value as well.""")
|
||||
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Colour"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.IsOk()')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Colour, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.red = val
|
||||
elif idx == 1: self.green = val
|
||||
elif idx == 2: self.blue = val
|
||||
elif idx == 3: self.alpha = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Rect.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Types that can be converted to wx.Colour:
|
||||
# wxColour (duh)
|
||||
# Sequence with 3 or 4 integers
|
||||
# String with color name or #RRGGBB or #RRGGBBAA format
|
||||
# None (converts to wxNullColour)
|
||||
c.allowNone = True
|
||||
c.convertFromPyObject = """\
|
||||
// is it just a typecheck?
|
||||
if (!sipIsErr) {
|
||||
if (sipPy == Py_None)
|
||||
return 1;
|
||||
if (sipCanConvertToType(sipPy, sipType_wxColour, SIP_NO_CONVERTORS))
|
||||
return 1;
|
||||
if (PyString_Check(sipPy) || PyUnicode_Check(sipPy))
|
||||
return 1;
|
||||
if (PySequence_Check(sipPy)) {
|
||||
size_t len = PySequence_Size(sipPy);
|
||||
if (len != 3 && len != 4)
|
||||
return 0;
|
||||
// ensure all the items in the sequence are numbers
|
||||
for (int idx=0; idx<len; idx+=1) {
|
||||
PyObject* o = PySequence_ITEM(sipPy, idx);
|
||||
bool isNum = PyNumber_Check(o);
|
||||
Py_DECREF(o);
|
||||
if (!isNum)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// otherwise do the conversion
|
||||
// is it None?
|
||||
if (sipPy == Py_None) {
|
||||
*sipCppPtr = new wxColour(wxNullColour);
|
||||
return sipGetState(sipTransferObj);
|
||||
}
|
||||
// Is it a string?
|
||||
else if (PyString_Check(sipPy) || PyUnicode_Check(sipPy)) {
|
||||
wxString spec = Py2wxString(sipPy);
|
||||
if (spec.GetChar(0) == '#'
|
||||
&& (spec.length() == 7 || spec.length() == 9)) { // It's #RRGGBB[AA]
|
||||
long red, green, blue;
|
||||
red = green = blue = 0;
|
||||
spec.Mid(1,2).ToLong(&red, 16);
|
||||
spec.Mid(3,2).ToLong(&green, 16);
|
||||
spec.Mid(5,2).ToLong(&blue, 16);
|
||||
|
||||
if (spec.length() == 7) // no alpha
|
||||
*sipCppPtr = new wxColour(red, green, blue);
|
||||
else { // yes alpha
|
||||
long alpha;
|
||||
spec.Mid(7,2).ToLong(&alpha, 16);
|
||||
*sipCppPtr = new wxColour(red, green, blue, alpha);
|
||||
}
|
||||
return sipGetState(sipTransferObj);
|
||||
}
|
||||
else { // assume it's a colour name
|
||||
// check if alpha is there too
|
||||
int pos;
|
||||
if (((pos = spec.Find(':', true)) != wxNOT_FOUND) && (pos == spec.length()-3)) {
|
||||
long alpha;
|
||||
spec.Right(2).ToLong(&alpha, 16);
|
||||
wxColour c = wxColour(spec.Left(spec.length()-3));
|
||||
*sipCppPtr = new wxColour(c.Red(), c.Green(), c.Blue(), alpha);
|
||||
}
|
||||
else
|
||||
*sipCppPtr = new wxColour(spec);
|
||||
return sipGetState(sipTransferObj);
|
||||
}
|
||||
}
|
||||
// Is it a 3 or 4 element sequence?
|
||||
else if (PySequence_Check(sipPy)) {
|
||||
size_t len = PyObject_Length(sipPy);
|
||||
|
||||
PyObject* o1 = PySequence_GetItem(sipPy, 0);
|
||||
PyObject* o2 = PySequence_GetItem(sipPy, 1);
|
||||
PyObject* o3 = PySequence_GetItem(sipPy, 2);
|
||||
if (len == 3)
|
||||
*sipCppPtr = new wxColour(PyInt_AsLong(o1), PyInt_AsLong(o2), PyInt_AsLong(o3));
|
||||
else {
|
||||
PyObject* o4 = PySequence_GetItem(sipPy, 3);
|
||||
*sipCppPtr = new wxColour(PyInt_AsLong(o1), PyInt_AsLong(o2), PyInt_AsLong(o3),
|
||||
PyInt_AsLong(o4));
|
||||
Py_DECREF(o4);
|
||||
}
|
||||
Py_DECREF(o1);
|
||||
Py_DECREF(o2);
|
||||
Py_DECREF(o3);
|
||||
return sipGetState(sipTransferObj);
|
||||
}
|
||||
|
||||
// if we get this far then it must already be a wxColour instance
|
||||
*sipCppPtr = reinterpret_cast<wxColour*>(sipConvertToType(
|
||||
sipPy, sipType_wxColour, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
|
||||
return sipGetState(sipTransferObj);
|
||||
"""
|
||||
|
||||
|
||||
|
||||
# Just for TESTING, remove it later
|
||||
module.addCppCode("""\
|
||||
wxColour testColourTypeMap(const wxColour& c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
extern void wxInitializeStockLists();
|
||||
""")
|
||||
module.addItem(etgtools.WigCode("""\
|
||||
wxColour testColourTypeMap(const wxColour& c);
|
||||
void wxInitializeStockLists();
|
||||
"""))
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
97
etg/defs.py
Normal file
97
etg/defs.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/defs.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 19-Nov-2010
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "defs" # 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 = [ 'defs_8h.xml' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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.
|
||||
|
||||
|
||||
# tweaks for defs.h
|
||||
module.find('wxInt16').type = 'short'
|
||||
module.find('wxInt64').type = 'long long'
|
||||
module.find('wxUint64').type = 'unsigned long long'
|
||||
module.find('wxIntPtr').type = 'long' #'ssize_t'
|
||||
module.find('wxUIntPtr').type = 'unsigned long' #'size_t'
|
||||
|
||||
module.find('wxDELETE').ignore()
|
||||
module.find('wxDELETEA').ignore()
|
||||
module.find('wxSwap').ignore()
|
||||
module.find('wxVaCopy').ignore()
|
||||
|
||||
# add some typedefs for wxChar, wxUChar
|
||||
td = module.find('wxUIntPtr')
|
||||
module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxUChar'))
|
||||
module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxChar'))
|
||||
|
||||
|
||||
# Remove these when the classes are added for real
|
||||
module.insertItem(0, etgtools.WigCode("class wxWindow; // forward declaration"))
|
||||
module.insertItem(0, etgtools.WigCode("class wxDC; // forward declaration"))
|
||||
module.insertItem(0, etgtools.WigCode("class wxMenu; // forward declaration"))
|
||||
module.insertItem(0, etgtools.WigCode("class wxCursor; // forward declaration"))
|
||||
|
||||
|
||||
# TBD: I've always disliked the WXK_* names. Should I rename all the items
|
||||
# in the wxKeyCode enum to be KEY_* names?
|
||||
|
||||
|
||||
# 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;
|
||||
const int SUBRELEASE_NUMBER = wxSUBRELEASE_NUMBER;
|
||||
""")
|
||||
module.addItem(etgtools.WigCode("""
|
||||
const int MAJOR_VERSION;
|
||||
const int MINOR_VERSION;
|
||||
const int RELEASE_NUMBER;
|
||||
const int SUBRELEASE_NUMBER;
|
||||
"""))
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
66
etg/display.py
Normal file
66
etg/display.py
Normal file
@@ -0,0 +1,66 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/display.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created:
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "display" # 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 = [ 'wxDisplay', ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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.addHeaderCode("#include <wx/display.h>")
|
||||
|
||||
c = module.find('wxDisplay')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
c.addPrivateAssignOp()
|
||||
c.addPrivateCopyCtor()
|
||||
|
||||
# TODO: SIP needs to know about wxArrayVideoModes before we can enable this
|
||||
c.find('GetModes').ignore()
|
||||
|
||||
c.addProperty('ClientArea GetClientArea')
|
||||
c.addProperty('CurrentMode GetCurrentMode')
|
||||
c.addProperty('Geometry GetGeometry')
|
||||
c.addProperty('Name GetName')
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
518
etg/event.py
518
etg/event.py
@@ -7,6 +7,9 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "event" # Base name of the file to generate to for this script
|
||||
@@ -61,267 +64,262 @@ ITEMS = [
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
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.addCppCode("""
|
||||
#if !wxUSE_HOTKEY
|
||||
#define wxEVT_HOTKEY 0
|
||||
#endif
|
||||
""")
|
||||
|
||||
module.insertItem(0, etgtools.WigCode("class wxWindow; // forward declaration"))
|
||||
module.insertItem(0, etgtools.WigCode("class wxDC; // forward declaration"))
|
||||
module.insertItem(0, etgtools.WigCode("class wxMenu; // forward declaration"))
|
||||
module.insertItem(0, etgtools.WigCode("class wxCursor; // forward declaration"))
|
||||
|
||||
# TODO:
|
||||
# * PyEventBinder class
|
||||
# * event binder instances for all the event types implemented here
|
||||
# * Connect, Bind etc. methods for EvtHandler
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxEvtHandler
|
||||
c = module.find('wxEvtHandler')
|
||||
c.addPrivateCopyCtor()
|
||||
|
||||
# Ignore the Connect/Disconnect and Bind/Unbind methods (and overloads) for now.
|
||||
for item in c.allItems():
|
||||
if item.name in ['Connect', 'Disconnect', 'Bind', 'Unbind']:
|
||||
item.ignore()
|
||||
|
||||
|
||||
# wxEventTable is not documented so we have to ignore SearchEventTable.
|
||||
# TODO: Should wxEventTable be available to language bindings?
|
||||
c.find('SearchEventTable').ignore()
|
||||
|
||||
# TODO: If we don't need to use the wxEvtHandler's client data for our own
|
||||
# tracking then enable these....
|
||||
c.find('GetClientObject').ignore()
|
||||
c.find('SetClientObject').ignore()
|
||||
c.find('GetClientData').ignore()
|
||||
c.find('SetClientData').ignore()
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxEvent
|
||||
c = module.find('wxEvent')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
c.abstract = True
|
||||
c.find('Clone').factory = True
|
||||
|
||||
c.addProperty('EventObject GetEventObject SetEventObject')
|
||||
c.addProperty('EventType GetEventType SetEventType')
|
||||
c.addProperty('Id GetId SetId')
|
||||
c.addProperty('Skipped GetSkipped')
|
||||
c.addProperty('Timestamp GetTimestamp SetTimestamp')
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxCommandEvent
|
||||
c = module.find('wxCommandEvent')
|
||||
|
||||
c.find('GetClientObject').ignore()
|
||||
c.find('SetClientObject').ignore()
|
||||
c.find('GetClientData').ignore()
|
||||
c.find('SetClientData').ignore()
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'GetClientData', '()', """\
|
||||
wxPyClientData* data = (wxPyClientData*)sipCpp->GetClientObject();
|
||||
if (data) {
|
||||
Py_INCREF(data->m_obj);
|
||||
sipRes = data->m_obj;
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
sipRes = Py_None;
|
||||
}
|
||||
""")
|
||||
|
||||
c.addCppMethod('void', 'SetClientData', '(SIP_PYOBJECT clientData)', """\
|
||||
wxPyClientData* data = new wxPyClientData(clientData);
|
||||
sipCpp->SetClientObject(data);
|
||||
""")
|
||||
|
||||
|
||||
c.addProperty('ClientData GetClientData SetClientData')
|
||||
c.addProperty('ExtraLong GetExtraLong SetExtraLong')
|
||||
c.addProperty('Int GetInt SetInt')
|
||||
c.addProperty('Selection GetSelection')
|
||||
c.addProperty('String GetString SetString')
|
||||
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.addCppCode("""
|
||||
#if !wxUSE_HOTKEY
|
||||
#define wxEVT_HOTKEY 0
|
||||
#endif
|
||||
""")
|
||||
|
||||
|
||||
# TODO:
|
||||
# * PyEventBinder class
|
||||
# * event binder instances for all the event types implemented here
|
||||
# * Connect, Bind etc. methods for EvtHandler
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxEvtHandler
|
||||
c = module.find('wxEvtHandler')
|
||||
c.addPrivateCopyCtor()
|
||||
|
||||
# Ignore the Connect/Disconnect and Bind/Unbind methods (and overloads) for now.
|
||||
for item in c.allItems():
|
||||
if item.name in ['Connect', 'Disconnect', 'Bind', 'Unbind']:
|
||||
item.ignore()
|
||||
|
||||
|
||||
# wxEventTable is not documented so we have to ignore SearchEventTable.
|
||||
# TODO: Should wxEventTable be available to language bindings?
|
||||
c.find('SearchEventTable').ignore()
|
||||
|
||||
# TODO: If we don't need to use the wxEvtHandler's client data for our own
|
||||
# tracking then enable these....
|
||||
c.find('GetClientObject').ignore()
|
||||
c.find('SetClientObject').ignore()
|
||||
c.find('GetClientData').ignore()
|
||||
c.find('SetClientData').ignore()
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxEvent
|
||||
c = module.find('wxEvent')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
c.abstract = True
|
||||
c.find('Clone').factory = True
|
||||
|
||||
c.addProperty('EventObject GetEventObject SetEventObject')
|
||||
c.addProperty('EventType GetEventType SetEventType')
|
||||
c.addProperty('Id GetId SetId')
|
||||
c.addProperty('Skipped GetSkipped')
|
||||
c.addProperty('Timestamp GetTimestamp SetTimestamp')
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxCommandEvent
|
||||
c = module.find('wxCommandEvent')
|
||||
|
||||
c.find('GetClientObject').ignore()
|
||||
c.find('SetClientObject').ignore()
|
||||
c.find('GetClientData').ignore()
|
||||
c.find('SetClientData').ignore()
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'GetClientData', '()', """\
|
||||
wxPyClientData* data = (wxPyClientData*)sipCpp->GetClientObject();
|
||||
if (data) {
|
||||
Py_INCREF(data->m_obj);
|
||||
sipRes = data->m_obj;
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
sipRes = Py_None;
|
||||
}
|
||||
""")
|
||||
|
||||
c.addCppMethod('void', 'SetClientData', '(SIP_PYOBJECT clientData)', """\
|
||||
wxPyClientData* data = new wxPyClientData(clientData);
|
||||
sipCpp->SetClientObject(data);
|
||||
""")
|
||||
|
||||
|
||||
c.addProperty('ClientData GetClientData SetClientData')
|
||||
c.addProperty('ExtraLong GetExtraLong SetExtraLong')
|
||||
c.addProperty('Int GetInt SetInt')
|
||||
c.addProperty('Selection GetSelection')
|
||||
c.addProperty('String GetString SetString')
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxKeyEvent
|
||||
c = module.find('wxKeyEvent')
|
||||
|
||||
c.find('GetPosition').findOverload('long').ignore()
|
||||
|
||||
c.addProperty('X GetX')
|
||||
c.addProperty('Y GetY')
|
||||
c.addProperty('KeyCode GetKeyCode')
|
||||
c.addProperty('Position GetPosition')
|
||||
c.addProperty('RawKeyCode GetRawKeyCode')
|
||||
c.addProperty('RawKeyFlags GetRawKeyFlags')
|
||||
c.addProperty('UnicodeKey GetUnicodeKey')
|
||||
|
||||
#---------------------------------------
|
||||
# wxScrollEvent
|
||||
c = module.find('wxScrollEvent')
|
||||
c.addProperty('Orientation GetOrientation SetOrientation')
|
||||
c.addProperty('Position GetPosition SetPosition')
|
||||
|
||||
#---------------------------------------
|
||||
# wxScrollWinEvent
|
||||
c = module.find('wxScrollWinEvent')
|
||||
c.addProperty('Orientation GetOrientation SetOrientation')
|
||||
c.addProperty('Position GetPosition SetPosition')
|
||||
|
||||
#---------------------------------------
|
||||
# wxMouseEvent
|
||||
c = module.find('wxMouseEvent')
|
||||
c.addProperty('LinesPerAction GetLinesPerAction')
|
||||
c.addProperty('LogicalPosition GetLogicalPosition')
|
||||
c.addProperty('WheelDelta GetWheelDelta')
|
||||
c.addProperty('WheelRotation GetWheelRotation')
|
||||
|
||||
#---------------------------------------
|
||||
# wxSetCursorEvent
|
||||
c = module.find('wxSetCursorEvent')
|
||||
c.addProperty('Cursor GetCursor SetCursor')
|
||||
c.addProperty('X GetX')
|
||||
c.addProperty('Y GetY')
|
||||
|
||||
#---------------------------------------
|
||||
# wxSizeEvent
|
||||
c = module.find('wxSizeEvent')
|
||||
c.addProperty('Rect GetRect SetRect')
|
||||
c.addProperty('Size GetSize SetSize')
|
||||
|
||||
#---------------------------------------
|
||||
# wxMoveEvent
|
||||
c = module.find('wxMoveEvent')
|
||||
c.addProperty('Rect GetRect SetRect')
|
||||
c.addProperty('Position GetPosition SetPosition')
|
||||
|
||||
#---------------------------------------
|
||||
# wxEraseEvent
|
||||
c = module.find('wxEraseEvent')
|
||||
c.addProperty('DC GetDC')
|
||||
|
||||
#---------------------------------------
|
||||
# wxFocusEvent
|
||||
c = module.find('wxFocusEvent')
|
||||
c.addProperty('Window GetWindow SetWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxChildFocusEvent
|
||||
c = module.find('wxChildFocusEvent')
|
||||
c.addProperty('Window GetWindow')
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxActivateEvent
|
||||
c = module.find('wxActivateEvent')
|
||||
c.addProperty('Active GetActive')
|
||||
|
||||
#---------------------------------------
|
||||
# wxMenuEvent
|
||||
c = module.find('wxMenuEvent')
|
||||
c.addProperty('Menu GetMenu')
|
||||
c.addProperty('MenuId GetMenuId')
|
||||
|
||||
#---------------------------------------
|
||||
# wxShowEvent
|
||||
c = module.find('wxShowEvent')
|
||||
c.find('GetShow').ignore() # deprecated
|
||||
c.addProperty('Show IsShown SetShow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxDropFilesEvent
|
||||
c = module.find('wxDropFilesEvent')
|
||||
c.addProperty('Files GetFiles')
|
||||
c.addProperty('NumberOfFiles GetNumberOfFiles')
|
||||
c.addProperty('Position GetPosition')
|
||||
|
||||
#---------------------------------------
|
||||
# wxUpdateUIEvent
|
||||
c = module.find('wxUpdateUIEvent')
|
||||
c.addProperty('Checked GetChecked Check')
|
||||
c.addProperty('Enabled GetEnabled Enable')
|
||||
c.addProperty('Shown GetShown Show')
|
||||
c.addProperty('Text GetText SetText')
|
||||
|
||||
#---------------------------------------
|
||||
# wxMouseCaptureChangedEvent
|
||||
c = module.find('wxMouseCaptureChangedEvent')
|
||||
c.addProperty('CapturedWindow GetCapturedWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxPaletteChangedEvent
|
||||
c = module.find('wxPaletteChangedEvent')
|
||||
c.addProperty('ChangedWindow GetChangedWindow SetChangedWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxQueryNewPaletteEvent
|
||||
c = module.find('wxQueryNewPaletteEvent')
|
||||
c.addProperty('PaletteRealized GetPaletteRealized SetPaletteRealized')
|
||||
|
||||
#---------------------------------------
|
||||
# wxNavigationKeyEvent
|
||||
c = module.find('wxNavigationKeyEvent')
|
||||
c.addProperty('CurrentFocus GetCurrentFocus SetCurrentFocus')
|
||||
c.addProperty('Direction GetDirection SetDirection')
|
||||
|
||||
#---------------------------------------
|
||||
# wxWindowCreateEvent
|
||||
c = module.find('wxWindowCreateEvent')
|
||||
c.addProperty('Window GetWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxWindowDestroyEvent
|
||||
c = module.find('wxWindowDestroyEvent')
|
||||
c.addProperty('Window GetWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxContextMenuEvent
|
||||
c = module.find('wxContextMenuEvent')
|
||||
c.addProperty('Position GetPosition SetPosition')
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxIconizeEvent
|
||||
module.find('wxIconizeEvent.Iconized').deprecated = True
|
||||
|
||||
|
||||
# Apply common fixups for all the event classes
|
||||
for name in [n for n in ITEMS if n.endswith('Event')]:
|
||||
c = module.find(name)
|
||||
tools.fixEventClass(c)
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxKeyEvent
|
||||
c = module.find('wxKeyEvent')
|
||||
|
||||
c.find('GetPosition').findOverload('long').ignore()
|
||||
|
||||
c.addProperty('X GetX')
|
||||
c.addProperty('Y GetY')
|
||||
c.addProperty('KeyCode GetKeyCode')
|
||||
c.addProperty('Position GetPosition')
|
||||
c.addProperty('RawKeyCode GetRawKeyCode')
|
||||
c.addProperty('RawKeyFlags GetRawKeyFlags')
|
||||
c.addProperty('UnicodeKey GetUnicodeKey')
|
||||
|
||||
#---------------------------------------
|
||||
# wxScrollEvent
|
||||
c = module.find('wxScrollEvent')
|
||||
c.addProperty('Orientation GetOrientation SetOrientation')
|
||||
c.addProperty('Position GetPosition SetPosition')
|
||||
|
||||
#---------------------------------------
|
||||
# wxScrollWinEvent
|
||||
c = module.find('wxScrollWinEvent')
|
||||
c.addProperty('Orientation GetOrientation SetOrientation')
|
||||
c.addProperty('Position GetPosition SetPosition')
|
||||
|
||||
#---------------------------------------
|
||||
# wxMouseEvent
|
||||
c = module.find('wxMouseEvent')
|
||||
c.addProperty('LinesPerAction GetLinesPerAction')
|
||||
c.addProperty('LogicalPosition GetLogicalPosition')
|
||||
c.addProperty('WheelDelta GetWheelDelta')
|
||||
c.addProperty('WheelRotation GetWheelRotation')
|
||||
|
||||
#---------------------------------------
|
||||
# wxSetCursorEvent
|
||||
c = module.find('wxSetCursorEvent')
|
||||
c.addProperty('Cursor GetCursor SetCursor')
|
||||
c.addProperty('X GetX')
|
||||
c.addProperty('Y GetY')
|
||||
|
||||
#---------------------------------------
|
||||
# wxSizeEvent
|
||||
c = module.find('wxSizeEvent')
|
||||
c.addProperty('Rect GetRect SetRect')
|
||||
c.addProperty('Size GetSize SetSize')
|
||||
|
||||
#---------------------------------------
|
||||
# wxMoveEvent
|
||||
c = module.find('wxMoveEvent')
|
||||
c.addProperty('Rect GetRect SetRect')
|
||||
c.addProperty('Position GetPosition SetPosition')
|
||||
|
||||
#---------------------------------------
|
||||
# wxEraseEvent
|
||||
c = module.find('wxEraseEvent')
|
||||
c.addProperty('DC GetDC')
|
||||
|
||||
#---------------------------------------
|
||||
# wxFocusEvent
|
||||
c = module.find('wxFocusEvent')
|
||||
c.addProperty('Window GetWindow SetWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxChildFocusEvent
|
||||
c = module.find('wxChildFocusEvent')
|
||||
c.addProperty('Window GetWindow')
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxActivateEvent
|
||||
c = module.find('wxActivateEvent')
|
||||
c.addProperty('Active GetActive')
|
||||
|
||||
#---------------------------------------
|
||||
# wxMenuEvent
|
||||
c = module.find('wxMenuEvent')
|
||||
c.addProperty('Menu GetMenu')
|
||||
c.addProperty('MenuId GetMenuId')
|
||||
|
||||
#---------------------------------------
|
||||
# wxShowEvent
|
||||
c = module.find('wxShowEvent')
|
||||
c.addProperty('Show IsShown SetShow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxDropFilesEvent
|
||||
c = module.find('wxDropFilesEvent')
|
||||
c.addProperty('Files GetFiles')
|
||||
c.addProperty('NumberOfFiles GetNumberOfFiles')
|
||||
c.addProperty('Position GetPosition')
|
||||
|
||||
#---------------------------------------
|
||||
# wxUpdateUIEvent
|
||||
c = module.find('wxUpdateUIEvent')
|
||||
c.addProperty('Checked GetChecked Check')
|
||||
c.addProperty('Enabled GetEnabled Enable')
|
||||
c.addProperty('Shown GetShown Show')
|
||||
c.addProperty('Text GetText SetText')
|
||||
|
||||
#---------------------------------------
|
||||
# wxMouseCaptureChangedEvent
|
||||
c = module.find('wxMouseCaptureChangedEvent')
|
||||
c.addProperty('CapturedWindow GetCapturedWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxPaletteChangedEvent
|
||||
c = module.find('wxPaletteChangedEvent')
|
||||
c.addProperty('ChangedWindow GetChangedWindow SetChangedWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxQueryNewPaletteEvent
|
||||
c = module.find('wxQueryNewPaletteEvent')
|
||||
c.addProperty('PaletteRealized GetPaletteRealized SetPaletteRealized')
|
||||
|
||||
#---------------------------------------
|
||||
# wxNavigationKeyEvent
|
||||
c = module.find('wxNavigationKeyEvent')
|
||||
c.addProperty('CurrentFocus GetCurrentFocus SetCurrentFocus')
|
||||
c.addProperty('Direction GetDirection SetDirection')
|
||||
#c.addProperty('FromTab IsFromTab SetFromTab')
|
||||
#c.addProperty('WindowChange IsWindowChange SetWindowChange')
|
||||
|
||||
# ignore the copy ctor because we'll be adding a private one below
|
||||
c.find('wxNavigationKeyEvent').findOverload('const wxNavigationKeyEvent').ignore()
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxWindowCreateEvent
|
||||
c = module.find('wxWindowCreateEvent')
|
||||
c.addProperty('Window GetWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxWindowDestroyEvent
|
||||
c = module.find('wxWindowDestroyEvent')
|
||||
c.addProperty('Window GetWindow')
|
||||
|
||||
#---------------------------------------
|
||||
# wxContextMenuEvent
|
||||
c = module.find('wxContextMenuEvent')
|
||||
c.addProperty('Position GetPosition SetPosition')
|
||||
|
||||
|
||||
|
||||
|
||||
# Apply common fixups for all the event classes
|
||||
for name in [n for n in ITEMS if n.endswith('Event')]:
|
||||
c = module.find(name)
|
||||
tools.fixEventClass(c)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
56
etg/evtloop.py
Normal file
56
etg/evtloop.py
Normal file
@@ -0,0 +1,56 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/evtloop.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 22-Nov-2010
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "evtloop" # 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 = [ 'wxEventLoopBase' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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('wxEventLoopBase')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
c.abstract = True
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
96
etg/font.py
Normal file
96
etg/font.py
Normal file
@@ -0,0 +1,96 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/font.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created:
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "font" # 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 = [ 'wxFont',
|
||||
#'wxFontList',
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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.find('wxFromString').ignore()
|
||||
module.find('wxToString').ignore()
|
||||
|
||||
# TODOs
|
||||
module.find('wxTheFontList').ignore()
|
||||
module.find('wxNORMAL_FONT').ignore()
|
||||
module.find('wxSMALL_FONT').ignore()
|
||||
module.find('wxITALIC_FONT').ignore()
|
||||
module.find('wxSWISS_FONT').ignore()
|
||||
|
||||
|
||||
c = module.find('wxFont')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
tools.removeVirtuals(c)
|
||||
|
||||
c.addCppCtor("""(
|
||||
int pointSize,
|
||||
wxFontFamily family,
|
||||
int flags = wxFONTFLAG_DEFAULT,
|
||||
const wxString & faceName = wxEmptyString,
|
||||
wxFontEncoding encoding = wxFONTENCODING_DEFAULT
|
||||
)""",
|
||||
body="""\
|
||||
// YUCK!
|
||||
wxFont* font = wxFont::New(pointSize, family, flags, *faceName, encoding);
|
||||
sipCpp = new sipwxFont(*font);
|
||||
delete font;
|
||||
""")
|
||||
|
||||
for item in c.findAll('New'):
|
||||
item.factory = True
|
||||
|
||||
c.addProperty('Encoding GetEncoding SetEncoding')
|
||||
c.addProperty('FaceName GetFaceName SetFaceName')
|
||||
c.addProperty('Family GetFamily SetFamily')
|
||||
c.addProperty('NativeFontInfoDesc GetNativeFontInfoDesc SetNativeFontInfo')
|
||||
c.addProperty('NativeFontInfoUserDesc GetNativeFontInfoUserDesc SetNativeFontInfoUserDesc')
|
||||
c.addProperty('PointSize GetPointSize SetPointSize')
|
||||
c.addProperty('PixelSize GetPixelSize SetPixelSize')
|
||||
c.addProperty('Style GetStyle SetStyle')
|
||||
c.addProperty('Underlined GetUnderlined SetUnderlined')
|
||||
c.addProperty('Weight GetWeight SetWeight')
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
594
etg/gdicmn.py
594
etg/gdicmn.py
@@ -1,5 +1,5 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: gdicmn.py
|
||||
# Name: etg/gdicmn.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 4-Nov-2010
|
||||
@@ -7,6 +7,9 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "gdicmn"
|
||||
@@ -14,305 +17,306 @@ DOCSTRING = ""
|
||||
|
||||
# The classes and/or the basename of the Doxygen XML files to be processed by
|
||||
# this script.
|
||||
ITEMS = [
|
||||
'wxPoint',
|
||||
'wxSize',
|
||||
'wxRect',
|
||||
'wxRealPoint',
|
||||
]
|
||||
ITEMS = [ 'wxPoint',
|
||||
'wxSize',
|
||||
'wxRect',
|
||||
'wxRealPoint',
|
||||
'wxColourDatabase' ,
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
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.
|
||||
|
||||
|
||||
# ignore some of these enum values
|
||||
e = module.find('wxBitmapType')
|
||||
for i in e:
|
||||
if i.name.endswith('_RESOURCE'):
|
||||
i.ignore()
|
||||
|
||||
module.addCppCode("""\
|
||||
#if !defined(__WXMAC__)
|
||||
#define wxCURSOR_COPY_ARROW wxCURSOR_ARROW
|
||||
#endif
|
||||
""")
|
||||
|
||||
# these are X11 only
|
||||
e = module.find('wxStockCursor')
|
||||
e.find('wxCURSOR_BASED_ARROW_DOWN').ignore()
|
||||
e.find('wxCURSOR_BASED_ARROW_UP').ignore()
|
||||
e.find('wxCURSOR_CROSS_REVERSE').ignore()
|
||||
e.find('wxCURSOR_DOUBLE_ARROW').ignore()
|
||||
|
||||
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.
|
||||
|
||||
|
||||
# ignore some of these enum values
|
||||
e = module.find('wxBitmapType')
|
||||
for i in e:
|
||||
if i.name.endswith('_RESOURCE'):
|
||||
i.ignore()
|
||||
|
||||
module.addCppCode("""\
|
||||
#if !defined(__WXMAC__)
|
||||
#define wxCURSOR_COPY_ARROW wxCURSOR_ARROW
|
||||
#endif
|
||||
""")
|
||||
|
||||
# these are X11 only
|
||||
e = module.find('wxStockCursor')
|
||||
e.find('wxCURSOR_BASED_ARROW_DOWN').ignore()
|
||||
e.find('wxCURSOR_BASED_ARROW_UP').ignore()
|
||||
e.find('wxCURSOR_CROSS_REVERSE').ignore()
|
||||
e.find('wxCURSOR_DOUBLE_ARROW').ignore()
|
||||
|
||||
|
||||
module.find('wxTheColourDatabase').ignore()
|
||||
module.find('wxSetCursor').ignore()
|
||||
|
||||
module.find('wxClientDisplayRect.x').out = True
|
||||
module.find('wxClientDisplayRect.y').out = True
|
||||
module.find('wxClientDisplayRect.width').out = True
|
||||
module.find('wxClientDisplayRect.height').out = True
|
||||
|
||||
module.find('wxDisplaySize.width').out = True
|
||||
module.find('wxDisplaySize.height').out = True
|
||||
module.find('wxDisplaySizeMM.width').out = True
|
||||
module.find('wxDisplaySizeMM.height').out = True
|
||||
|
||||
#---------------------------------------
|
||||
# wxPoint tweaks
|
||||
c = module.find('wxPoint')
|
||||
|
||||
# Some operators are documented within the class that shouldn't be, so just
|
||||
# ignore them all.
|
||||
tools.ignoreAllOperators(c)
|
||||
|
||||
# Undo a few of those ignores for legitimate items that were
|
||||
# documented correctly
|
||||
for f in c.find('operator+=').all() + c.find('operator-=').all():
|
||||
f.ignore(False)
|
||||
|
||||
module.find('wxTheColourDatabase').ignore() # TODO
|
||||
module.find('wxSetCursor').ignore() # TODO
|
||||
|
||||
module.find('wxClientDisplayRect.x').out = True
|
||||
module.find('wxClientDisplayRect.y').out = True
|
||||
module.find('wxClientDisplayRect.width').out = True
|
||||
module.find('wxClientDisplayRect.height').out = True
|
||||
|
||||
module.find('wxDisplaySize.width').out = True
|
||||
module.find('wxDisplaySize.height').out = True
|
||||
module.find('wxDisplaySizeMM.width').out = True
|
||||
module.find('wxDisplaySizeMM.height').out = True
|
||||
|
||||
#---------------------------------------
|
||||
# wxPoint tweaks
|
||||
c = module.find('wxPoint')
|
||||
|
||||
# Some operators are documented within the class that shouldn't be, so just
|
||||
# ignore them all.
|
||||
tools.ignoreAllOperators(c)
|
||||
|
||||
# Undo a few of those ignores for legitimate items that were
|
||||
# documented correctly
|
||||
for f in c.find('operator+=').all() + c.find('operator-=').all():
|
||||
f.ignore(False)
|
||||
# Add some stand-alone function declarations for the operators that really do
|
||||
# exist.
|
||||
wc = etgtools.WigCode("""\
|
||||
bool operator==(const wxPoint& p1, const wxPoint& p2);
|
||||
bool operator!=(const wxPoint& p1, const wxPoint& p2);
|
||||
wxPoint operator+(const wxPoint& p, const wxSize& s);
|
||||
wxPoint operator+(const wxPoint& p1, const wxPoint& p2);
|
||||
wxPoint operator+(const wxSize& s, const wxPoint& p);
|
||||
wxPoint operator-(const wxPoint& p);
|
||||
wxPoint operator-(const wxPoint& p, const wxSize& s);
|
||||
wxPoint operator-(const wxPoint& p1, const wxPoint& p2);
|
||||
wxPoint operator-(const wxSize& s, const wxPoint& p);
|
||||
wxPoint operator*(const wxPoint& s, int i);
|
||||
wxPoint operator*(int i, const wxPoint& s);
|
||||
wxPoint operator/(const wxPoint& s, int i);
|
||||
""")
|
||||
module.insertItemAfter(c, wc)
|
||||
|
||||
# Add some stand-alone function declarations for the operators that really do
|
||||
# exist.
|
||||
wc = etgtools.WigCode("""\
|
||||
bool operator==(const wxPoint& p1, const wxPoint& p2);
|
||||
bool operator!=(const wxPoint& p1, const wxPoint& p2);
|
||||
wxPoint operator+(const wxPoint& p, const wxSize& s);
|
||||
wxPoint operator+(const wxPoint& p1, const wxPoint& p2);
|
||||
wxPoint operator+(const wxSize& s, const wxPoint& p);
|
||||
wxPoint operator-(const wxPoint& p);
|
||||
wxPoint operator-(const wxPoint& p, const wxSize& s);
|
||||
wxPoint operator-(const wxPoint& p1, const wxPoint& p2);
|
||||
wxPoint operator-(const wxSize& s, const wxPoint& p);
|
||||
wxPoint operator*(const wxPoint& s, int i);
|
||||
wxPoint operator*(int i, const wxPoint& s);
|
||||
wxPoint operator/(const wxPoint& s, int i);
|
||||
""")
|
||||
module.insertItemAfter(c, wc)
|
||||
|
||||
|
||||
# wxPoint typemap
|
||||
c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxPoint')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(ii)", sipCpp->x, sipCpp->y);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x,y)\n
|
||||
Return the x and y properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Point"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Point, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Point.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxSize tweaks
|
||||
c = module.find('wxSize')
|
||||
|
||||
c.addProperty("width GetWidth SetWidth")
|
||||
c.addProperty("height GetHeight SetHeight")
|
||||
|
||||
# take care of the same issues as wxPoint
|
||||
tools.ignoreAllOperators(c)
|
||||
for f in c.find('operator+=').all() + \
|
||||
c.find('operator-=').all() + \
|
||||
c.find('operator*=').all() + \
|
||||
c.find('operator/=').all():
|
||||
f.ignore(False)
|
||||
wc = etgtools.WigCode("""\
|
||||
bool operator==(const wxSize& s1, const wxSize& s2);
|
||||
bool operator!=(const wxSize& s1, const wxSize& s2);
|
||||
wxSize operator*(const wxSize& s, int i);
|
||||
wxSize operator*(int i, const wxSize& s);
|
||||
wxSize operator+(const wxSize& s1, const wxSize& s2);
|
||||
wxSize operator-(const wxSize& s1, const wxSize& s2);
|
||||
wxSize operator/(const wxSize& s, int i);
|
||||
""")
|
||||
module.insertItemAfter(c, wc)
|
||||
|
||||
|
||||
# wxSize typemap
|
||||
c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxSize')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(ii)", sipCpp->GetWidth(), sipCpp->GetHeight());
|
||||
""", briefDoc="""\
|
||||
Get() -> (width, height)\n
|
||||
Return the width and height properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Size"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Size, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.width = val
|
||||
elif idx == 1: self.height = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Size.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxRect tweaks
|
||||
c = module.find('wxRect')
|
||||
|
||||
c.addProperty("left GetLeft")
|
||||
c.addProperty("top GetTop")
|
||||
c.addProperty("right GetRight")
|
||||
c.addProperty("bottom GetBottom")
|
||||
|
||||
c.addProperty("bottomLeft GetBottomLeft")
|
||||
c.addProperty("bottomRight GetBottomRight")
|
||||
c.addProperty("topLeft GetTopLeft")
|
||||
c.addProperty("topRight GetTopRight")
|
||||
|
||||
# take care of the same issues as wxPoint
|
||||
tools.ignoreAllOperators(c)
|
||||
for f in c.find('operator+=').all() + \
|
||||
c.find('operator*=').all():
|
||||
f.ignore(False)
|
||||
wc = etgtools.WigCode("""\
|
||||
bool operator==(const wxRect& r1, const wxRect& r2);
|
||||
bool operator!=(const wxRect& r1, const wxRect& r2);
|
||||
wxRect operator+(const wxRect& r1, const wxRect& r2);
|
||||
wxRect operator*(const wxRect& r1, const wxRect& r2);
|
||||
""")
|
||||
module.insertItemAfter(c, wc)
|
||||
|
||||
# Because of our add-ons that make wx.Point and wx.Size act like 2-element
|
||||
# sequences, and also the typecheck code that allows 2-element sequences, then
|
||||
# we end up with a bit of confusion about the (Point,Point) and the
|
||||
# (Point,Size) overloads of the wx.Rect constructor. The confusion can be
|
||||
# dealt with by using keyword args, but I think that the (Point,Size) version
|
||||
# will be used more, so reorder the overloads so it is found first.
|
||||
m = module.find('wxRect.wxRect')
|
||||
mo = m.findOverload('topLeft')
|
||||
del m.overloads[m.overloads.index(mo)]
|
||||
m.overloads.append(mo)
|
||||
|
||||
# These methods have some overloads that will end up with the same signature
|
||||
# in Python, so we have to remove one.
|
||||
module.find('wxRect.Deflate').findOverload(') const').ignore()
|
||||
module.find('wxRect.Inflate').findOverload(') const').ignore()
|
||||
module.find('wxRect.Union').findOverload(') const').ignore()
|
||||
module.find('wxRect.Intersect').findOverload(') const').ignore()
|
||||
|
||||
# wxRect typemap
|
||||
c.convertFromPyObject = tools.convertFourIntegersTemplate('wxRect')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(iiii)",
|
||||
sipCpp->x, sipCpp->y, sipCpp->width, sipCpp->height);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x, y, width, height)\n
|
||||
Return the rectangle's properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Rect"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0,0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Rect, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
elif idx == 2: self.width = val
|
||||
elif idx == 3: self.height = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Rect.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxRealPoint tweaks
|
||||
c = module.find('wxRealPoint')
|
||||
|
||||
# take care of the same issues as wxPoint
|
||||
tools.ignoreAllOperators(c)
|
||||
for f in c.find('operator+=').all() + \
|
||||
c.find('operator-=').all():
|
||||
f.ignore(False)
|
||||
wc = etgtools.WigCode("""\
|
||||
bool operator==(const wxRealPoint& p1, const wxRealPoint& p2);
|
||||
bool operator!=(const wxRealPoint& p1, const wxRealPoint& p2);
|
||||
wxRealPoint operator*(const wxRealPoint& s, double i);
|
||||
wxRealPoint operator*(double i, const wxRealPoint& s);
|
||||
wxRealPoint operator+(const wxRealPoint& p1, const wxRealPoint& p2);
|
||||
wxRealPoint operator-(const wxRealPoint& p1, const wxRealPoint& p2);
|
||||
wxRealPoint operator/(const wxRealPoint& s, int i);
|
||||
""")
|
||||
module.insertItemAfter(c, wc)
|
||||
|
||||
|
||||
# wxRealPoint typemap
|
||||
c.convertFromPyObject = tools.convertTwoDoublesTemplate('wxRealPoint')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(dd)",
|
||||
sipCpp->x, sipCpp->y);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x, y, width, height)\n
|
||||
Return the rectangle's properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.RealPoint"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Rect, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('RealPoint.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
# wxPoint typemap
|
||||
c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxPoint')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(ii)", sipCpp->x, sipCpp->y);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x,y)\n
|
||||
Return the x and y properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Point"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Point, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Point.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxSize tweaks
|
||||
c = module.find('wxSize')
|
||||
|
||||
c.addProperty("width GetWidth SetWidth")
|
||||
c.addProperty("height GetHeight SetHeight")
|
||||
|
||||
# take care of the same issues as wxPoint
|
||||
tools.ignoreAllOperators(c)
|
||||
for f in c.find('operator+=').all() + \
|
||||
c.find('operator-=').all() + \
|
||||
c.find('operator*=').all() + \
|
||||
c.find('operator/=').all():
|
||||
f.ignore(False)
|
||||
wc = etgtools.WigCode("""\
|
||||
bool operator==(const wxSize& s1, const wxSize& s2);
|
||||
bool operator!=(const wxSize& s1, const wxSize& s2);
|
||||
wxSize operator*(const wxSize& s, int i);
|
||||
wxSize operator*(int i, const wxSize& s);
|
||||
wxSize operator+(const wxSize& s1, const wxSize& s2);
|
||||
wxSize operator-(const wxSize& s1, const wxSize& s2);
|
||||
wxSize operator/(const wxSize& s, int i);
|
||||
""")
|
||||
module.insertItemAfter(c, wc)
|
||||
|
||||
|
||||
# wxSize typemap
|
||||
c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxSize')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(ii)", sipCpp->GetWidth(), sipCpp->GetHeight());
|
||||
""", briefDoc="""\
|
||||
Get() -> (width, height)\n
|
||||
Return the width and height properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Size"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Size, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.width = val
|
||||
elif idx == 1: self.height = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Size.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxRect tweaks
|
||||
c = module.find('wxRect')
|
||||
|
||||
c.addProperty("left GetLeft")
|
||||
c.addProperty("top GetTop")
|
||||
c.addProperty("right GetRight")
|
||||
c.addProperty("bottom GetBottom")
|
||||
|
||||
c.addProperty("bottomLeft GetBottomLeft")
|
||||
c.addProperty("bottomRight GetBottomRight")
|
||||
c.addProperty("topLeft GetTopLeft")
|
||||
c.addProperty("topRight GetTopRight")
|
||||
|
||||
# take care of the same issues as wxPoint
|
||||
tools.ignoreAllOperators(c)
|
||||
for f in c.find('operator+=').all() + \
|
||||
c.find('operator*=').all():
|
||||
f.ignore(False)
|
||||
wc = etgtools.WigCode("""\
|
||||
bool operator==(const wxRect& r1, const wxRect& r2);
|
||||
bool operator!=(const wxRect& r1, const wxRect& r2);
|
||||
wxRect operator+(const wxRect& r1, const wxRect& r2);
|
||||
wxRect operator*(const wxRect& r1, const wxRect& r2);
|
||||
""")
|
||||
module.insertItemAfter(c, wc)
|
||||
|
||||
# Because of our add-ons that make wx.Point and wx.Size act like 2-element
|
||||
# sequences, and also the typecheck code that allows 2-element sequences, then
|
||||
# we end up with a bit of confusion about the (Point,Point) and the
|
||||
# (Point,Size) overloads of the wx.Rect constructor. The confusion can be
|
||||
# dealt with by using keyword args, but I think that the (Point,Size) version
|
||||
# will be used more, so reorder the overloads so it is found first.
|
||||
m = module.find('wxRect.wxRect')
|
||||
mo = m.findOverload('topLeft')
|
||||
del m.overloads[m.overloads.index(mo)]
|
||||
m.overloads.append(mo)
|
||||
|
||||
# These methods have some overloads that will end up with the same signature
|
||||
# in Python, so we have to remove one.
|
||||
module.find('wxRect.Deflate').findOverload(') const').ignore()
|
||||
module.find('wxRect.Inflate').findOverload(') const').ignore()
|
||||
module.find('wxRect.Union').findOverload(') const').ignore()
|
||||
module.find('wxRect.Intersect').findOverload(') const').ignore()
|
||||
|
||||
# wxRect typemap
|
||||
c.convertFromPyObject = tools.convertFourIntegersTemplate('wxRect')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(iiii)",
|
||||
sipCpp->x, sipCpp->y, sipCpp->width, sipCpp->height);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x, y, width, height)\n
|
||||
Return the rectangle's properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Rect"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0,0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Rect, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
elif idx == 2: self.width = val
|
||||
elif idx == 3: self.height = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Rect.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxRealPoint tweaks
|
||||
c = module.find('wxRealPoint')
|
||||
|
||||
# take care of the same issues as wxPoint
|
||||
tools.ignoreAllOperators(c)
|
||||
for f in c.find('operator+=').all() + \
|
||||
c.find('operator-=').all():
|
||||
f.ignore(False)
|
||||
wc = etgtools.WigCode("""\
|
||||
bool operator==(const wxRealPoint& p1, const wxRealPoint& p2);
|
||||
bool operator!=(const wxRealPoint& p1, const wxRealPoint& p2);
|
||||
wxRealPoint operator*(const wxRealPoint& s, double i);
|
||||
wxRealPoint operator*(double i, const wxRealPoint& s);
|
||||
wxRealPoint operator+(const wxRealPoint& p1, const wxRealPoint& p2);
|
||||
wxRealPoint operator-(const wxRealPoint& p1, const wxRealPoint& p2);
|
||||
wxRealPoint operator/(const wxRealPoint& s, int i);
|
||||
""")
|
||||
module.insertItemAfter(c, wc)
|
||||
|
||||
|
||||
# wxRealPoint typemap
|
||||
c.convertFromPyObject = tools.convertTwoDoublesTemplate('wxRealPoint')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(dd)",
|
||||
sipCpp->x, sipCpp->y);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x, y, width, height)\n
|
||||
Return the rectangle's properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.RealPoint"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Rect, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('RealPoint.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
55
etg/gdiobj.py
Normal file
55
etg/gdiobj.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/gdiobj.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created:
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "gdiobj" # 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 = [ 'wxGDIObject' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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.find('wxGDIObject').abstract = True
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
240
etg/geometry.py
240
etg/geometry.py
@@ -1,5 +1,5 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: geometry.py
|
||||
# Name: etg/geometry.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 4-Nov-2010
|
||||
@@ -7,6 +7,9 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "geometry"
|
||||
@@ -20,125 +23,126 @@ ITEMS = [
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
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.addHeaderCode('#include <wx/wx.h>')
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxPoint2D and wxRect2D tweaks
|
||||
|
||||
c = module.find('wxPoint2DDouble')
|
||||
c.pyName = 'Point2D'
|
||||
c.find('wxPoint2DDouble').findOverload('wxPoint2DInt').ignore()
|
||||
|
||||
c.find('m_x').pyName = 'x'
|
||||
c.find('m_y').pyName = 'y'
|
||||
c.find('GetFloor.x').out = True
|
||||
c.find('GetFloor.y').out = True
|
||||
c.find('GetRounded.x').out = True
|
||||
c.find('GetRounded.y').out = True
|
||||
|
||||
# these have link errors
|
||||
c.find('SetPolarCoordinates').ignore()
|
||||
c.find('operator/=').findOverload('wxDouble').ignore()
|
||||
c.find('operator*=').findOverload('wxDouble').ignore()
|
||||
|
||||
|
||||
c.convertFromPyObject = tools.convertTwoDoublesTemplate('wxPoint2DDouble')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(dd)", sipCpp->m_x, sipCpp->m_y);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x,y)\n
|
||||
Return the x and y properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Point2D"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Point2D, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Point2D.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
# ignore these operator methods, since we are not wrapping the Int version
|
||||
c.find('operator*=').findOverload('wxInt32').ignore()
|
||||
c.find('operator/=').findOverload('wxInt32').ignore()
|
||||
|
||||
# ignore some of the global operators too
|
||||
for item in module:
|
||||
if isinstance(item, etgtools.FunctionDef) and item.type == 'wxPoint2DInt':
|
||||
item.ignore()
|
||||
if item.name in ['operator*', 'operator/'] and 'wxInt32' in item.argsString:
|
||||
item.ignore()
|
||||
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.addHeaderCode('#include <wx/wx.h>')
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# wxPoint2D and wxRect2D tweaks
|
||||
|
||||
c = module.find('wxPoint2DDouble')
|
||||
c.pyName = 'Point2D'
|
||||
c.find('wxPoint2DDouble').findOverload('wxPoint2DInt').ignore()
|
||||
|
||||
c.find('m_x').pyName = 'x'
|
||||
c.find('m_y').pyName = 'y'
|
||||
c.find('GetFloor.x').out = True
|
||||
c.find('GetFloor.y').out = True
|
||||
c.find('GetRounded.x').out = True
|
||||
c.find('GetRounded.y').out = True
|
||||
|
||||
# these have link errors
|
||||
c.find('SetPolarCoordinates').ignore()
|
||||
c.find('operator/=').findOverload('wxDouble').ignore()
|
||||
c.find('operator*=').findOverload('wxDouble').ignore()
|
||||
|
||||
|
||||
c.convertFromPyObject = tools.convertTwoDoublesTemplate('wxPoint2DDouble')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(dd)", sipCpp->m_x, sipCpp->m_y);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x,y)\n
|
||||
Return the x and y properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Point2D"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Point2D, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Point2D.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
# ignore these operator methods, since we are not wrapping the Int version
|
||||
c.find('operator*=').findOverload('wxInt32').ignore()
|
||||
c.find('operator/=').findOverload('wxInt32').ignore()
|
||||
|
||||
# ignore some of the global operators too
|
||||
for item in module:
|
||||
if isinstance(item, etgtools.FunctionDef) and item.type == 'wxPoint2DInt':
|
||||
item.ignore()
|
||||
if item.name in ['operator*', 'operator/'] and 'wxInt32' in item.argsString:
|
||||
item.ignore()
|
||||
|
||||
|
||||
c = module.find('wxRect2DDouble')
|
||||
c.pyName = 'Rect2D'
|
||||
c.find('m_x').pyName = 'x'
|
||||
c.find('m_y').pyName = 'y'
|
||||
c.find('m_width').pyName = 'width'
|
||||
c.find('m_height').pyName = 'height'
|
||||
|
||||
c.convertFromPyObject = tools.convertFourDoublesTemplate('wxRect2DDouble')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(dddd)",
|
||||
sipCpp->m_x, sipCpp->m_y, sipCpp->m_width, sipCpp->m_height);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x, y, width, height)\n
|
||||
Return the rectangle's properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Rect2D"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0,0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Rect2D, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
elif idx == 2: self.width = val
|
||||
elif idx == 3: self.height = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Rect2D.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
|
||||
|
||||
c = module.find('wxRect2DDouble')
|
||||
c.pyName = 'Rect2D'
|
||||
c.find('m_x').pyName = 'x'
|
||||
c.find('m_y').pyName = 'y'
|
||||
c.find('m_width').pyName = 'width'
|
||||
c.find('m_height').pyName = 'height'
|
||||
|
||||
c.convertFromPyObject = tools.convertFourDoublesTemplate('wxRect2DDouble')
|
||||
|
||||
c.addCppMethod('SIP_PYOBJECT', 'Get', '()', """\
|
||||
sipRes = sipBuildResult(&sipIsErr, "(dddd)",
|
||||
sipCpp->m_x, sipCpp->m_y, sipCpp->m_width, sipCpp->m_height);
|
||||
""", briefDoc="""\
|
||||
Get() -> (x, y, width, height)\n
|
||||
Return the rectangle's properties as a tuple.""")
|
||||
|
||||
# Add sequence protocol methods and other goodies
|
||||
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
|
||||
c.addPyMethod('__repr__', '(self)', 'return "wx.Rect2D"+str(self.Get())')
|
||||
c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
|
||||
c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0,0,0)')
|
||||
c.addPyMethod('__reduce__', '(self)', 'return (Rect2D, self.Get())')
|
||||
c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
|
||||
c.addPyMethod('__setitem__', '(self, idx, val)',
|
||||
"""\
|
||||
if idx == 0: self.x = val
|
||||
elif idx == 1: self.y = val
|
||||
elif idx == 2: self.width = val
|
||||
elif idx == 3: self.height = val
|
||||
else: raise IndexError
|
||||
""")
|
||||
c.addPyCode('Rect2D.__safe_for_unpickling__ = True')
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
66
etg/intl.py
Normal file
66
etg/intl.py
Normal file
@@ -0,0 +1,66 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/intl.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created:
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "intl" # 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 = [ 'wxLanguageInfo',
|
||||
'wxLocale',
|
||||
|
||||
'language_8h.xml',
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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('wxLocale')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
c.addPrivateAssignOp()
|
||||
c.addPrivateCopyCtor()
|
||||
tools.removeVirtuals(c)
|
||||
|
||||
|
||||
c = module.find('wxLanguageInfo')
|
||||
c.find('WinLang').ignore()
|
||||
c.find('WinSublang').ignore()
|
||||
c.find('GetLCID').ignore()
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "kbdstate" # Base name of the file to generate to for this script
|
||||
@@ -17,40 +20,41 @@ DOCSTRING = ""
|
||||
ITEMS = [ 'wxKeyboardState' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, 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.
|
||||
|
||||
|
||||
c = module.find('wxKeyboardState')
|
||||
|
||||
c.addProperty("controlDown ControlDown SetControlDown")
|
||||
c.addProperty("shiftDown ShiftDown SetShiftDown")
|
||||
c.addProperty("altDown AltDown SetAltDown")
|
||||
c.addProperty("metaDown MetaDown SetMetaDown")
|
||||
c.addProperty("cmdDown CmdDown")
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for customizing
|
||||
# the generated code and docstrings.
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
|
||||
c = module.find('wxKeyboardState')
|
||||
|
||||
c.addProperty("controlDown ControlDown SetControlDown")
|
||||
c.addProperty("shiftDown ShiftDown SetShiftDown")
|
||||
c.addProperty("altDown AltDown SetAltDown")
|
||||
c.addProperty("metaDown MetaDown SetMetaDown")
|
||||
c.addProperty("cmdDown CmdDown")
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "mousestate" # Base name of the file to generate to for this script
|
||||
@@ -17,44 +20,45 @@ DOCSTRING = ""
|
||||
ITEMS = [ 'wxMouseState' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, 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.
|
||||
|
||||
|
||||
c = module.find('wxMouseState')
|
||||
c.find('GetPosition').findOverload('int *x').ignore()
|
||||
|
||||
c.addProperty("x GetX SetX")
|
||||
c.addProperty("y GetY SetY")
|
||||
c.addProperty("leftIsDown LeftIsDown SetLeftDown")
|
||||
c.addProperty("middleIsDown MiddleIsDown SetMiddleDown")
|
||||
c.addProperty("rightIsDown RightIsDown SetRightDown")
|
||||
c.addProperty("aux1IsDown Aux1IsDown SetAux1Down")
|
||||
c.addProperty("aux2IsDown Aux2IsDown SetAux2Down")
|
||||
c.addProperty("Position GetPosition SetPosition")
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for customizing
|
||||
# the generated code and docstrings.
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
|
||||
c = module.find('wxMouseState')
|
||||
c.find('GetPosition').findOverload('int *x').ignore()
|
||||
|
||||
c.addProperty("x GetX SetX")
|
||||
c.addProperty("y GetY SetY")
|
||||
c.addProperty("leftIsDown LeftIsDown SetLeftDown")
|
||||
c.addProperty("middleIsDown MiddleIsDown SetMiddleDown")
|
||||
c.addProperty("rightIsDown RightIsDown SetRightDown")
|
||||
c.addProperty("aux1IsDown Aux1IsDown SetAux1Down")
|
||||
c.addProperty("aux2IsDown Aux2IsDown SetAux2Down")
|
||||
c.addProperty("Position GetPosition SetPosition")
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: object.py
|
||||
# Name: etg/object.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 9-Nov-2010
|
||||
@@ -7,6 +7,9 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "object" # Base name of the file to generate to for this script
|
||||
@@ -17,45 +20,62 @@ DOCSTRING = ""
|
||||
ITEMS = [
|
||||
'wxRefCounter',
|
||||
'wxObject',
|
||||
'wxClassInfo',
|
||||
# 'wxClassInfo',
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, 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.
|
||||
|
||||
|
||||
module.find('wxObject.operator delete').ignore()
|
||||
module.find('wxObject.operator new').ignore()
|
||||
module.find('wxCreateDynamicObject').ignore()
|
||||
|
||||
|
||||
#module.find('wxClassInfo').abstract = True
|
||||
#module.find('wxClassInfo.wxClassInfo').ignore()
|
||||
|
||||
module.find('wxObject.GetClassInfo').ignore()
|
||||
module.find('wxObject.IsKindOf').ignore()
|
||||
|
||||
module.find('wxRefCounter.~wxRefCounter').ignore(False)
|
||||
|
||||
c = module.find('wxObject')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
|
||||
c.addCppMethod('const wxChar*', 'GetClassName', '()',
|
||||
body='sipRes = sipCpp->GetClassInfo()->GetClassName();',
|
||||
doc='Returns the class name of the C++ class using wxRTTI.')
|
||||
|
||||
c.addCppMethod('void', 'Destroy', '()',
|
||||
body='delete sipCpp;',
|
||||
doc='Deletes the C++ object this Python object is a proxy for.',
|
||||
transferThis=True) # TODO: Check this
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for customizing
|
||||
# the generated code and docstrings.
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
|
||||
module.find('wxObject.operator delete').ignore()
|
||||
module.find('wxObject.operator new').ignore()
|
||||
module.find('wxCreateDynamicObject').ignore()
|
||||
|
||||
|
||||
module.find('wxClassInfo').abstract = True
|
||||
module.find('wxClassInfo.wxClassInfo').ignore()
|
||||
|
||||
module.find('wxRefCounter.~wxRefCounter').ignore(False)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
59
etg/platinfo.py
Normal file
59
etg/platinfo.py
Normal file
@@ -0,0 +1,59 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/platinfo.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 22-Nov-2010
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "platinfo" # 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 = [ 'wxPlatformInfo' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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('wxPlatformInfo')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
|
||||
c.find('wxPlatformInfo').findOverload('()').ignore()
|
||||
c.find('GetLinuxDistributionInfo').ignore()
|
||||
c.find('SetLinuxDistributionInfo').ignore()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name:
|
||||
# Name: etg/????
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created:
|
||||
@@ -7,6 +7,9 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = ""
|
||||
MODULE = ""
|
||||
NAME = "" # Base name of the file to generate to for this script
|
||||
@@ -17,35 +20,36 @@ DOCSTRING = ""
|
||||
ITEMS = [ ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, 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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for customizing
|
||||
# the generated code and docstrings.
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "tracker" # Base name of the file to generate to for this script
|
||||
@@ -17,36 +20,37 @@ DOCSTRING = ""
|
||||
ITEMS = [ 'wxTrackable' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, 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.
|
||||
|
||||
|
||||
c = module.find('wxTrackable')
|
||||
c.abstract = True
|
||||
c.addDtor('private')
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for customizing
|
||||
# the generated code and docstrings.
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
|
||||
c = module.find('wxTrackable')
|
||||
c.abstract = True
|
||||
c.addDtor('private')
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
54
etg/vidmode.py
Normal file
54
etg/vidmode.py
Normal file
@@ -0,0 +1,54 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/vidmode.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created:
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "vidmode" # 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 = [ 'wxVideoMode' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "windowid" # Base name of the file to generate to for this script
|
||||
@@ -17,35 +20,36 @@ DOCSTRING = ""
|
||||
ITEMS = [ 'wxIdManager' ]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, 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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#-----------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for customizing
|
||||
# the generated code and docstrings.
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
tools.ignoreAssignmentOperators(module)
|
||||
tools.removeWxPrefixes(module)
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the generators
|
||||
|
||||
# Create the code generator and make the wrapper code
|
||||
wg = etgtools.getWrapperGenerator()
|
||||
wg.generate(module)
|
||||
|
||||
# Create a documentation generator and let it do its thing
|
||||
dg = etgtools.getDocsGenerator()
|
||||
dg.generate(module)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -45,9 +45,9 @@ def parseDoxyXML(module, class_or_filename_list):
|
||||
Doxygen XML output folder.
|
||||
"""
|
||||
|
||||
def _classToDoxyName(name):
|
||||
def _classToDoxyName(name, base='class'):
|
||||
import string
|
||||
filename = 'class'
|
||||
filename = base
|
||||
for c in name:
|
||||
if c in string.ascii_uppercase:
|
||||
filename += '_' + c.lower()
|
||||
@@ -58,12 +58,19 @@ def parseDoxyXML(module, class_or_filename_list):
|
||||
def _includeToDoxyName(name):
|
||||
name = os.path.basename(name)
|
||||
name = name.replace('.h', '_8h')
|
||||
return os.path.join(XMLSRC, name) + '.xml', name + '.xml'
|
||||
pathname = os.path.join(XMLSRC, name) + '.xml'
|
||||
if os.path.exists(pathname):
|
||||
return pathname, name + '.xml'
|
||||
else:
|
||||
name = 'interface_2wx_2' + name
|
||||
return os.path.join(XMLSRC, name) + '.xml', name + '.xml'
|
||||
|
||||
for class_or_filename in class_or_filename_list:
|
||||
pathname = _classToDoxyName(class_or_filename)
|
||||
if not os.path.exists(pathname):
|
||||
pathname = os.path.join(XMLSRC, class_or_filename)
|
||||
pathname = _classToDoxyName(class_or_filename, 'struct')
|
||||
if not os.path.exists(pathname):
|
||||
pathname = os.path.join(XMLSRC, class_or_filename)
|
||||
if verbose():
|
||||
print "Loading %s..." % pathname
|
||||
_filesparsed.add(pathname)
|
||||
|
||||
@@ -17,12 +17,6 @@ import os
|
||||
import pprint
|
||||
import xml.etree.ElementTree as et
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# TODOs
|
||||
#
|
||||
# * Need a way to idicate that items are not available on certain platforms
|
||||
#
|
||||
# * Something for TypeHeader code for classes
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -143,6 +137,17 @@ class BaseDef(object):
|
||||
items.extend(o.allItems())
|
||||
return items
|
||||
|
||||
|
||||
def findAll(self, name):
|
||||
"""
|
||||
Search recursivly for items that have the given name.
|
||||
"""
|
||||
matches = list()
|
||||
for item in self.allItems():
|
||||
if item.name == name or item.pyName == name:
|
||||
matches.append(item)
|
||||
return matches
|
||||
|
||||
|
||||
def _findItems(self):
|
||||
# If there are more items to be searched than what is in self.items, a
|
||||
@@ -240,9 +245,10 @@ class FunctionDef(BaseDef):
|
||||
self.factory = False # a factory function that creates a new instance of the return value
|
||||
self.pyReleaseGIL = False # release the Python GIL for this function call
|
||||
self.noCopy = False # don't make a copy of the return value, just wrap the original
|
||||
self.pyInt = False # treat char types as integers
|
||||
self.transfer = False # transfer ownership of return value to C++?
|
||||
self.transferBack = False # transfer ownership of return value from C++ to Python?
|
||||
self.transferThis = False # ownership of 'this' pointer transfered to this arg
|
||||
self.transferThis = False # ownership of 'this' pointer transfered to C++
|
||||
self.__dict__.update(kw)
|
||||
if element is not None:
|
||||
self.extract(element)
|
||||
@@ -338,7 +344,8 @@ class MethodDef(FunctionDef):
|
||||
self.isCtor = False
|
||||
self.isDtor = False
|
||||
self.protection = ''
|
||||
self.defaultCtor = False # use this ctor as the default one
|
||||
self.defaultCtor = False # use this ctor as the default one
|
||||
self.noDerivedCtor = False # don't generate a ctor in the derived class for this ctor
|
||||
self.__dict__.update(kw)
|
||||
if element is not None:
|
||||
self.extract(element, className)
|
||||
@@ -383,6 +390,7 @@ class ParamDef(BaseDef):
|
||||
self.default = '' # default value
|
||||
self.out = False # is it an output arg?
|
||||
self.inOut = False # is it both input and output?
|
||||
self.pyInt = False # treat char types as integers
|
||||
self.array = False # the param is to be treated as an array
|
||||
self.arraySize = False # the param is the size of the array
|
||||
self.transfer = False # transfer ownership of arg to C++?
|
||||
@@ -422,8 +430,9 @@ class ClassDef(BaseDef):
|
||||
The information about a class that is needed to generate wrappers for it.
|
||||
"""
|
||||
nameTag = 'compoundname'
|
||||
def __init__(self, element=None, **kw):
|
||||
def __init__(self, element=None, kind='class', **kw):
|
||||
super(ClassDef, self).__init__()
|
||||
self.kind = kind
|
||||
self.bases = [] # base class names
|
||||
self.includes = [] # .h file for this class
|
||||
self.abstract = False # is it an abstract base class?
|
||||
@@ -431,8 +440,11 @@ class ClassDef(BaseDef):
|
||||
self.external = False # class is in another module
|
||||
self.noDefCtor = False # do not generate a default constructor
|
||||
self.singlton = False # class is a singleton so don't call the dtor until the interpreter exits
|
||||
self.convertFromPyObject = None
|
||||
self.headerCode = []
|
||||
self.cppCode = []
|
||||
self.convertToPyObject = None
|
||||
self.convertFromPyObject = None
|
||||
self.allowNone = False # Allow the convertFrom code to handle None too.
|
||||
|
||||
# Stuff that needs to be generated after the class instead of within
|
||||
# it. Some back-end generators need to put stuff inside the class, and
|
||||
@@ -494,6 +506,23 @@ class ClassDef(BaseDef):
|
||||
_print("\n", indent, stream)
|
||||
|
||||
|
||||
def addHeaderCode(self, code):
|
||||
if isinstance(code, list):
|
||||
self.headerCode.extend(code)
|
||||
else:
|
||||
self.headerCode.append(code)
|
||||
|
||||
def addCppCode(self, code):
|
||||
if isinstance(code, list):
|
||||
self.cppCode.extend(code)
|
||||
else:
|
||||
self.cppCode.append(code)
|
||||
|
||||
|
||||
def insertCppCode(self, filename):
|
||||
self.addCppCode(file(filename).read())
|
||||
|
||||
|
||||
def addProperty(self, *args, **kw):
|
||||
"""
|
||||
Add a property to a class, with a name, getter function and optionally
|
||||
@@ -529,11 +558,12 @@ class ClassDef(BaseDef):
|
||||
return md
|
||||
|
||||
|
||||
def addCppCtor(self, argsString, body, doc=None, **kw):
|
||||
def addCppCtor(self, argsString, body, doc=None, noDerivedCtor=True, **kw):
|
||||
"""
|
||||
Add a C++ method that is a constructor.
|
||||
"""
|
||||
md = CppMethodDef('', self.name, argsString, body, doc=doc, isCtor=True, **kw)
|
||||
md = CppMethodDef('', self.name, argsString, body, doc=doc,
|
||||
isCtor=True, noDerivedCtor=noDerivedCtor, **kw)
|
||||
self.items.append(md)
|
||||
return md
|
||||
|
||||
@@ -590,10 +620,9 @@ class ClassDef(BaseDef):
|
||||
|
||||
def addCopyCtor(self, prot='protected'):
|
||||
# add declaration of a copy constructor to this class
|
||||
wig = WigCode("""
|
||||
wig = WigCode("""\
|
||||
{PROT}:
|
||||
{CLASS}(const {CLASS}&);
|
||||
""".format(CLASS=self.name, PROT=prot))
|
||||
{CLASS}(const {CLASS}&);""".format(CLASS=self.name, PROT=prot))
|
||||
self.addItem(wig)
|
||||
|
||||
def addPrivateCopyCtor(self):
|
||||
@@ -601,18 +630,16 @@ class ClassDef(BaseDef):
|
||||
|
||||
def addPrivateAssignOp(self):
|
||||
# add declaration of an assignment opperator to this class
|
||||
wig = WigCode("""
|
||||
wig = WigCode("""\
|
||||
private:
|
||||
{CLASS}& operator=(const {CLASS}&);
|
||||
""".format(CLASS=self.name))
|
||||
{CLASS}& operator=(const {CLASS}&);""".format(CLASS=self.name))
|
||||
self.addItem(wig)
|
||||
|
||||
def addDtor(self, prot='protected'):
|
||||
# add declaration of a destructor to this class
|
||||
wig = WigCode("""
|
||||
wig = WigCode("""\
|
||||
{PROT}:
|
||||
~{CLASS}();
|
||||
""".format(CLASS=self.name, PROT=prot))
|
||||
~{CLASS}();""".format(CLASS=self.name, PROT=prot))
|
||||
self.addItem(wig)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -702,14 +729,13 @@ class CppMethodDef(MethodDef):
|
||||
NOTE: This one is not automatically extracted, but can be added to
|
||||
classes in the tweaker stage
|
||||
"""
|
||||
def __init__(self, type, name, argsString, body, doc=None, isCtor=False, **kw):
|
||||
def __init__(self, type, name, argsString, body, doc=None, **kw):
|
||||
super(CppMethodDef, self).__init__()
|
||||
self.type = type
|
||||
self.name = name
|
||||
self.argsString = argsString
|
||||
self.body = body
|
||||
self.briefDoc = doc
|
||||
self.isCtor = isCtor
|
||||
self.protection = 'public'
|
||||
self.__dict__.update(kw)
|
||||
|
||||
@@ -745,9 +771,10 @@ class PyCodeDef(BaseDef):
|
||||
This code held by this class will be written to a Python module
|
||||
that wraps the import of the extension module.
|
||||
"""
|
||||
def __init__(self, code, **kw):
|
||||
def __init__(self, code, order=None, **kw):
|
||||
super(PyCodeDef, self).__init__()
|
||||
self.code = code
|
||||
self.order = order
|
||||
self.__dict__.update(kw)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -838,6 +865,11 @@ class ModuleDef(BaseDef):
|
||||
item = ClassDef(element)
|
||||
self.items.append(item)
|
||||
|
||||
elif kind == 'struct':
|
||||
extractingMsg(kind, element, ClassDef.nameTag)
|
||||
item = ClassDef(element, kind='struct')
|
||||
self.items.append(item)
|
||||
|
||||
elif kind == 'function':
|
||||
extractingMsg(kind, element)
|
||||
item = FunctionDef(element)
|
||||
@@ -903,15 +935,29 @@ class ModuleDef(BaseDef):
|
||||
return md
|
||||
|
||||
|
||||
def addPyCode(self, code):
|
||||
def addPyCode(self, code, order=None):
|
||||
"""
|
||||
Add a snippet of Python code to the wrapper module.
|
||||
"""
|
||||
pc = PyCodeDef(code)
|
||||
pc = PyCodeDef(code, order)
|
||||
self.items.append(pc)
|
||||
return pc
|
||||
|
||||
|
||||
def includePyCode(self, filename, order=None):
|
||||
"""
|
||||
Add a snippet of Python code from a file to the wrapper module.
|
||||
"""
|
||||
text = file(filename).read()
|
||||
return self.addPyCode(
|
||||
"#" + '-=' * 38 + '\n' +
|
||||
("# This code block was included from %s\n%s\n" % (filename, text)) +
|
||||
"# End of included code block\n"
|
||||
"#" + '-=' * 38 + '\n' ,
|
||||
order
|
||||
)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Some helper functions and such
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -67,7 +67,7 @@ class SipWrapperGenerator(generators.WrapperGeneratorBase):
|
||||
if module.docstring:
|
||||
doc = '\n"""\n%s\n"""\n' % module.docstring
|
||||
stream.write("""\
|
||||
%%Extract pycode
|
||||
%%Extract(id=pycode, order=5)
|
||||
# This file is generated by wxPython's SIP generator. Do not edit by hand.
|
||||
#
|
||||
# Copyright: (c) 2010 by Total Control Software
|
||||
@@ -140,6 +140,7 @@ from %s import *
|
||||
extractors.TypedefDef : self.generateTypedef,
|
||||
extractors.WigCode : self.generateWigCode,
|
||||
extractors.PyCodeDef : self.generatePyCode,
|
||||
extractors.CppMethodDef : self.generateCppMethod,
|
||||
}
|
||||
|
||||
for item in module:
|
||||
@@ -169,9 +170,9 @@ from %s import *
|
||||
continue
|
||||
stream.write(indent)
|
||||
stream.write('%s %s' % (param.type, param.name))
|
||||
stream.write(self.annotate(param))
|
||||
if param.default:
|
||||
stream.write(' = %s' % param.default)
|
||||
stream.write(self.annotate(param))
|
||||
if not idx == len(parameters)-1:
|
||||
stream.write(',')
|
||||
stream.write('\n')
|
||||
@@ -226,7 +227,10 @@ from %s import *
|
||||
if hasattr(pc, 'klass') and pc.klass.generatingInClass:
|
||||
pc.klass.generateAfterClass.append(pc)
|
||||
else:
|
||||
stream.write('%Extract pycode\n')
|
||||
stream.write('%Extract(id=pycode')
|
||||
if pc.order is not None:
|
||||
stream.write(', order=%d' % pc.order)
|
||||
stream.write(')\n')
|
||||
stream.write(nci(pc.code))
|
||||
stream.write('\n%End\n\n')
|
||||
|
||||
@@ -238,18 +242,35 @@ from %s import *
|
||||
return
|
||||
|
||||
# write the class header
|
||||
stream.write('%sclass %s' % (indent, klass.name))
|
||||
stream.write('%s%s %s' % (indent, klass.kind, klass.name))
|
||||
if klass.bases:
|
||||
stream.write(' : ')
|
||||
stream.write(', '.join(klass.bases))
|
||||
stream.write(self.annotate(klass))
|
||||
stream.write('\n%s{\n' % indent)
|
||||
indent2 = indent + ' '*4
|
||||
if klass.includes:
|
||||
stream.write('%s%%TypeHeaderCode\n' % indent)
|
||||
stream.write('%s%%TypeHeaderCode\n' % indent2)
|
||||
for inc in klass.includes:
|
||||
stream.write('%s #include <%s>\n' % (indent, inc))
|
||||
stream.write('%s%%End\n' % indent)
|
||||
stream.write('\n%spublic:\n' % indent)
|
||||
stream.write('%s #include <%s>\n' % (indent2, inc))
|
||||
stream.write('%s%%End\n\n' % indent2)
|
||||
|
||||
# C++ code to be written to the Type's header
|
||||
if klass.headerCode:
|
||||
stream.write("%s%%TypeHeaderCode\n" % indent2)
|
||||
for c in klass.headerCode:
|
||||
stream.write(nci(c, len(indent2)+4))
|
||||
stream.write("%s%%End\n" % indent2)
|
||||
|
||||
# C++ code to be written out to the this Type's wrapper code module
|
||||
if klass.cppCode:
|
||||
stream.write("%s%%TypeCode\n" % indent2)
|
||||
for c in klass.cppCode:
|
||||
stream.write(nci(c, len(indent2)+4))
|
||||
stream.write("%s%%End\n" % indent2)
|
||||
|
||||
if klass.kind == 'class':
|
||||
stream.write('\n%spublic:\n' % indent)
|
||||
|
||||
# is the generator currently inside the class or after it?
|
||||
klass.generatingInClass = True
|
||||
@@ -357,7 +378,7 @@ from %s import *
|
||||
self.generateMethod(m, stream, indent)
|
||||
|
||||
|
||||
def generateCppMethod(self, method, stream, indent):
|
||||
def generateCppMethod(self, method, stream, indent=''):
|
||||
assert isinstance(method, extractors.CppMethodDef)
|
||||
if method.ignored:
|
||||
return
|
||||
@@ -385,6 +406,7 @@ from %s import *
|
||||
stream.write(nci('"""\n%s\n"""\n' % pm.briefDoc, 4))
|
||||
stream.write(nci(pm.body, 4))
|
||||
stream.write('%s.%s = _%s_%s\n' % (klassName, pm.name, klassName, pm.name))
|
||||
stream.write('del _%s_%s\n' % (klassName, pm.name))
|
||||
stream.write('\n%End\n\n')
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
@@ -412,6 +434,8 @@ from %s import *
|
||||
annotations.append('TransferBack')
|
||||
if item.transferThis:
|
||||
annotations.append('TranserThis')
|
||||
if item.pyInt:
|
||||
annotations.append('PyInt')
|
||||
|
||||
if isinstance(item, extractors.FunctionDef):
|
||||
if item.deprecated:
|
||||
@@ -426,10 +450,14 @@ from %s import *
|
||||
if isinstance(item, extractors.MethodDef):
|
||||
if item.defaultCtor:
|
||||
annotations.append('Default')
|
||||
if item.noDerivedCtor:
|
||||
annotations.append('NoDerived')
|
||||
|
||||
if isinstance(item, extractors.ClassDef):
|
||||
if item.abstract:
|
||||
annotations.append('Abstract')
|
||||
if item.allowNone:
|
||||
annotations.append('AllowNone')
|
||||
if item.deprecated:
|
||||
annotations.append('Deprecated')
|
||||
if item.external:
|
||||
@@ -454,7 +482,7 @@ def nci(text, numSpaces=0, stripLeading=True):
|
||||
First use the count of leading spaces on the first line and remove that
|
||||
many spaces from the front of all lines, and then indent each line by
|
||||
adding numSpaces spaces. This is used so we can convert the arbitrary
|
||||
indents that might be used by the treaker code into what is expected for
|
||||
indents that might be used by the tweaker code into what is expected for
|
||||
the context we are generating for.
|
||||
"""
|
||||
def _getLeadingSpaceCount(line):
|
||||
@@ -464,8 +492,6 @@ def nci(text, numSpaces=0, stripLeading=True):
|
||||
if c != ' ':
|
||||
break
|
||||
count += 1
|
||||
else:
|
||||
assert False, "First line should not be empty."
|
||||
return count
|
||||
|
||||
def _allSpaces(text):
|
||||
|
||||
@@ -13,7 +13,7 @@ stage of the ETG scripts.
|
||||
"""
|
||||
|
||||
import extractors
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def removeWxPrefixes(node):
|
||||
@@ -82,6 +82,48 @@ def fixEventClass(klass):
|
||||
|
||||
|
||||
|
||||
def removeVirtuals(klass):
|
||||
"""
|
||||
Sometimes methods are marked as virtual but probably don't ever need to be
|
||||
overridden from Python. This function will unset the virtual flag for all
|
||||
methods in a class, which can save some code-bloat in the wrapper code.
|
||||
"""
|
||||
assert isinstance(klass, extractors.ClassDef)
|
||||
for item in klass.allItems():
|
||||
if isinstance(item, extractors.MethodDef):
|
||||
item.isVirtual = item.isPureVirtual = False
|
||||
|
||||
|
||||
def getEtgFiles(names):
|
||||
"""
|
||||
Create a list of the files from the basenames in the names list that
|
||||
corespond to files in the etg folder.
|
||||
"""
|
||||
return getMatchingFiles(names, 'etg/%s.py')
|
||||
|
||||
|
||||
def getNonEtgFiles(names, template='src/%s.sip'):
|
||||
"""
|
||||
Get the files other than the ETG scripts from the list of names that match
|
||||
the template. By default gets the SIP files in src.
|
||||
"""
|
||||
return getMatchingFiles(names, template)
|
||||
|
||||
|
||||
def getMatchingFiles(names, template):
|
||||
"""
|
||||
Create a list of files from the basenames in names that match the template
|
||||
and actually exist.
|
||||
"""
|
||||
files = list()
|
||||
for name in names:
|
||||
name = template % name
|
||||
if os.path.exists(name):
|
||||
files.append(name)
|
||||
return files
|
||||
|
||||
|
||||
|
||||
def convertTwoIntegersTemplate(CLASS):
|
||||
return """\
|
||||
// is it just a typecheck?
|
||||
@@ -113,7 +155,7 @@ def convertTwoIntegersTemplate(CLASS):
|
||||
}}
|
||||
*sipCppPtr = reinterpret_cast<{CLASS}*>(sipConvertToType(
|
||||
sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
|
||||
return 0;
|
||||
return sipGetState(sipTransferObj);
|
||||
""".format(**locals())
|
||||
|
||||
|
||||
@@ -155,7 +197,7 @@ def convertFourIntegersTemplate(CLASS):
|
||||
}}
|
||||
*sipCppPtr = reinterpret_cast<{CLASS}*>(sipConvertToType(
|
||||
sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
|
||||
return 0;
|
||||
return sipGetState(sipTransferObj);
|
||||
""".format(**locals())
|
||||
|
||||
|
||||
@@ -191,7 +233,7 @@ def convertTwoDoublesTemplate(CLASS):
|
||||
}}
|
||||
*sipCppPtr = reinterpret_cast<{CLASS}*>(sipConvertToType(
|
||||
sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
|
||||
return 0;
|
||||
return sipGetState(sipTransferObj);
|
||||
""".format(**locals())
|
||||
|
||||
|
||||
@@ -233,7 +275,7 @@ def convertFourDoublesTemplate(CLASS):
|
||||
}}
|
||||
*sipCppPtr = reinterpret_cast<{CLASS}*>(sipConvertToType(
|
||||
sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
|
||||
return 0;
|
||||
return sipGetState(sipTransferObj);
|
||||
""".format(**locals())
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import sys
|
||||
|
||||
# stuff for debugging
|
||||
import os
|
||||
import wxPhoenix as wx
|
||||
print "pid:", os.getpid()
|
||||
#print "executable:", sys.executable; raw_input("Press Enter...")
|
||||
|
||||
if sys.version_info < (2,7):
|
||||
# The unittest2 package has back-ported most of the new features of the
|
||||
# unittest module in Python 2.7, you can get it at PyPI.
|
||||
|
||||
74
setup.py
74
setup.py
@@ -14,10 +14,10 @@ import sys, os
|
||||
from distutils.core import setup, Extension
|
||||
from distutils.file_util import copy_file
|
||||
from distutils.dir_util import mkpath
|
||||
from distutils.dep_util import newer
|
||||
from distutils.dep_util import newer, newer_group
|
||||
from distutils.spawn import spawn
|
||||
|
||||
from buildtools.config import Config, msg, opj
|
||||
from buildtools.config import Config, msg, opj, loadETG
|
||||
import buildtools.distutils_hacks as hacks
|
||||
|
||||
|
||||
@@ -76,20 +76,34 @@ HEADERS = None
|
||||
BUILD_OPTIONS = { 'build_base' : cfg.BUILD_BASE }
|
||||
if cfg.WXPORT == 'msw':
|
||||
BUILD_OPTIONS[ 'compiler' ] = cfg.COMPILER
|
||||
|
||||
|
||||
|
||||
copy_file('src/__init__.py', cfg.PKGDIR, update=1, verbose=0)
|
||||
cfg.CLEANUP.append(opj(cfg.PKGDIR, '__init__.py'))
|
||||
|
||||
# update the license files
|
||||
mkpath('license')
|
||||
for file in ['preamble.txt', 'licence.txt', 'licendoc.txt', 'lgpl.txt']:
|
||||
copy_file(opj(cfg.WXDIR, 'docs', file), opj('license',file), update=1, verbose=0)
|
||||
cfg.CLEANUP.append(opj('license',file))
|
||||
for filename in ['preamble.txt', 'licence.txt', 'licendoc.txt', 'lgpl.txt']:
|
||||
copy_file(opj(cfg.WXDIR, 'docs', filename), opj('license',filename), update=1, verbose=0)
|
||||
cfg.CLEANUP.append(opj('license',filename))
|
||||
cfg.CLEANUP.append('license')
|
||||
|
||||
|
||||
# create the package's __version__ module
|
||||
open(opj(cfg.PKGDIR, '__version__.py'), 'w').write("""\
|
||||
# This file was generated by setup.py...
|
||||
|
||||
VERSION_STRING = '%(VERSION)s'
|
||||
MAJOR_VERSION = %(VER_MAJOR)s
|
||||
MINOR_VERSION = %(VER_MINOR)s
|
||||
RELEASE_NUMBER = %(VER_RELEASE)s
|
||||
SUBRELEASE_NUMBER = %(VER_SUBREL)s
|
||||
|
||||
VERSION = (MAJOR_VERSION, MINOR_VERSION, RELEASE_NUMBER,
|
||||
SUBRELEASE_NUMBER, '%(VER_FLAGS)s')
|
||||
""" % cfg.__dict__)
|
||||
cfg.CLEANUP.append(opj(cfg.PKGDIR,'__version__.py'))
|
||||
|
||||
|
||||
if sys.platform in ['win32', 'darwin']:
|
||||
cfg.build_locale_dir(opj(cfg.PKGDIR, 'locale'))
|
||||
DATA_FILES += cfg.build_locale_list(opj(cfg.PKGDIR, 'locale'))
|
||||
@@ -103,9 +117,9 @@ else:
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
ext = []
|
||||
extensions = []
|
||||
|
||||
ext.append(
|
||||
extensions.append(
|
||||
Extension('siplib', ['sip/siplib/apiversions.c',
|
||||
'sip/siplib/bool.cpp',
|
||||
'sip/siplib/descriptors.c',
|
||||
@@ -122,30 +136,22 @@ ext.append(
|
||||
extra_compile_args = cfg.cflags,
|
||||
extra_link_args = cfg.lflags,
|
||||
))
|
||||
|
||||
ext.append(
|
||||
Extension('_core', ['etg/_core.py',
|
||||
'etg/windowid.py',
|
||||
'etg/object.py',
|
||||
|
||||
'etg/kbdstate.py',
|
||||
'etg/mousestate.py',
|
||||
'etg/tracker.py',
|
||||
'etg/event.py',
|
||||
|
||||
'etg/gdicmn.py',
|
||||
'etg/geometry.py',
|
||||
] + rc_file,
|
||||
depends = [ 'src/string.sip',
|
||||
'src/clntdata.sip',
|
||||
],
|
||||
include_dirs = cfg.includes,
|
||||
define_macros = cfg.defines,
|
||||
library_dirs = cfg.libdirs,
|
||||
libraries = cfg.libs,
|
||||
extra_compile_args = cfg.cflags,
|
||||
extra_link_args = cfg.lflags,
|
||||
))
|
||||
|
||||
|
||||
etg = loadETG('etg/_core.py')
|
||||
ext = Extension('_core',
|
||||
#['src/core_utils.cpp'] +
|
||||
etg.ETGFILES + rc_file,
|
||||
depends = etg.DEPENDS,
|
||||
|
||||
include_dirs = cfg.includes,
|
||||
define_macros = cfg.defines,
|
||||
library_dirs = cfg.libdirs,
|
||||
libraries = cfg.libs,
|
||||
extra_compile_args = cfg.cflags,
|
||||
extra_link_args = cfg.lflags,
|
||||
)
|
||||
extensions.append(ext)
|
||||
cfg.CLEANUP.append(opj(cfg.PKGDIR, 'core.py'))
|
||||
|
||||
|
||||
@@ -168,7 +174,7 @@ if __name__ == '__main__':
|
||||
packages = WX_PKGLIST,
|
||||
#extra_path = EXTRA_PATH,
|
||||
ext_package = cfg.PKGDIR,
|
||||
ext_modules = ext,
|
||||
ext_modules = extensions,
|
||||
|
||||
options = { 'build' : BUILD_OPTIONS,
|
||||
'build_ext' : {'sip_opts' : cfg.SIPOPTS },
|
||||
|
||||
220
src/app_ex.cpp
Normal file
220
src/app_ex.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#include <gdk/gdkx.h>
|
||||
#include <wx/gtk/private/win_gtk.h>
|
||||
#endif
|
||||
|
||||
#ifdef __WXMAC__
|
||||
#include <wx/osx/private.h>
|
||||
#endif
|
||||
|
||||
|
||||
class wxPyApp : public wxApp
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(wxPyApp)
|
||||
|
||||
public:
|
||||
wxPyApp() : wxApp() {
|
||||
m_assertMode = wxPYAPP_ASSERT_EXCEPTION;
|
||||
m_startupComplete = false;
|
||||
//m_callFilterEvent = false;
|
||||
ms_appInstance = this;
|
||||
}
|
||||
~wxPyApp() {
|
||||
ms_appInstance = NULL;
|
||||
wxApp::SetInstance(NULL);
|
||||
}
|
||||
|
||||
|
||||
#ifndef __WXMAC__
|
||||
virtual void MacNewFile() {}
|
||||
virtual void MacOpenFile(const wxString &) {}
|
||||
virtual void MacOpenURL(const wxString &) {}
|
||||
virtual void MacPrintFile(const wxString &) {}
|
||||
virtual void MacReopenApp() {}
|
||||
#endif
|
||||
|
||||
#ifdef __WXMAC__
|
||||
static long GetMacAboutMenuItemId() { return s_macAboutMenuItemId; }
|
||||
static long GetMacPreferencesMenuItemId() { return s_macPreferencesMenuItemId; }
|
||||
static long GetMacExitMenuItemId() { return s_macExitMenuItemId; }
|
||||
static wxString GetMacHelpMenuTitleName() { return s_macHelpMenuTitleName; }
|
||||
static void SetMacAboutMenuItemId(long val) { s_macAboutMenuItemId = val; }
|
||||
static void SetMacPreferencesMenuItemId(long val) { s_macPreferencesMenuItemId = val; }
|
||||
static void SetMacExitMenuItemId(long val) { s_macExitMenuItemId = val; }
|
||||
static void SetMacHelpMenuTitleName(const wxString& val) { s_macHelpMenuTitleName = val; }
|
||||
#else
|
||||
static long GetMacAboutMenuItemId() { return 0; }
|
||||
static long GetMacPreferencesMenuItemId() { return 0; }
|
||||
static long GetMacExitMenuItemId() { return 0; }
|
||||
static wxString GetMacHelpMenuTitleName() { return wxEmptyString; }
|
||||
static void SetMacAboutMenuItemId(long) { }
|
||||
static void SetMacPreferencesMenuItemId(long) { }
|
||||
static void SetMacExitMenuItemId(long) { }
|
||||
static void SetMacHelpMenuTitleName(const wxString&) { }
|
||||
#endif
|
||||
|
||||
wxAppAssertMode GetAssertMode() { return m_assertMode; }
|
||||
void SetAssertMode(wxAppAssertMode mode) { m_assertMode = mode; }
|
||||
|
||||
// virtual void OnAssertFailure(const wxChar *file,
|
||||
// int line,
|
||||
// const wxChar *func,
|
||||
// const wxChar *cond,
|
||||
// const wxChar *msg);
|
||||
|
||||
|
||||
// Implementing OnInit is optional for wxPython apps
|
||||
virtual bool OnInit() { return true; }
|
||||
virtual void OnPreInit() { }
|
||||
|
||||
void _BootstrapApp();
|
||||
|
||||
static bool IsDisplayAvailable();
|
||||
|
||||
// implementation only
|
||||
void SetStartupComplete(bool val) { m_startupComplete = val; }
|
||||
static wxPyApp* ms_appInstance;
|
||||
|
||||
private:
|
||||
wxAppAssertMode m_assertMode;
|
||||
bool m_startupComplete;
|
||||
//bool m_callFilterEvent;
|
||||
};
|
||||
|
||||
IMPLEMENT_ABSTRACT_CLASS(wxPyApp, wxApp);
|
||||
|
||||
wxPyApp* wxPyApp::ms_appInstance = NULL;
|
||||
|
||||
|
||||
|
||||
void wxPyApp::_BootstrapApp()
|
||||
{
|
||||
static bool haveInitialized = false;
|
||||
bool result;
|
||||
wxPyBlock_t blocked;
|
||||
PyObject* retval = NULL;
|
||||
PyObject* pyint = NULL;
|
||||
|
||||
// Only initialize wxWidgets once
|
||||
if (! haveInitialized) {
|
||||
// Get any command-line args passed to this program from the sys module
|
||||
int argc = 0;
|
||||
char** argv = NULL;
|
||||
blocked = wxPyBeginBlockThreads();
|
||||
|
||||
PyObject* sysargv = PySys_GetObject("argv");
|
||||
PyObject* executable = PySys_GetObject("executable");
|
||||
|
||||
if (sysargv != NULL && executable != NULL) {
|
||||
argc = PyList_Size(sysargv) + 1;
|
||||
argv = new char*[argc+1];
|
||||
argv[0] = strdup(PyString_AsString(executable));
|
||||
int x;
|
||||
for(x=1; x<argc; x++) {
|
||||
PyObject *pyArg = PyList_GetItem(sysargv, x-1);
|
||||
argv[x] = strdup(PyString_AsString(pyArg));
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
|
||||
// Initialize wxWidgets
|
||||
#ifdef __WXOSX__
|
||||
wxMacAutoreleasePool autoreleasePool;
|
||||
#endif
|
||||
result = wxEntryStart(argc, argv);
|
||||
// wxApp takes ownership of the argv array, don't delete it here
|
||||
|
||||
blocked = wxPyBeginBlockThreads();
|
||||
if (! result) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"wxEntryStart failed, unable to initialize wxWidgets!"
|
||||
#ifdef __WXGTK__
|
||||
" (Is DISPLAY set properly?)"
|
||||
#endif
|
||||
);
|
||||
goto error;
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
haveInitialized = true;
|
||||
}
|
||||
else {
|
||||
this->argc = 0;
|
||||
}
|
||||
|
||||
// It's now ok to generate exceptions for assertion errors.
|
||||
SetStartupComplete(true);
|
||||
|
||||
// Call the Python wxApp's OnPreInit and OnInit functions if they exist
|
||||
OnPreInit();
|
||||
result = OnInit();
|
||||
|
||||
blocked = wxPyBeginBlockThreads();
|
||||
if (! result) {
|
||||
PyErr_SetString(PyExc_SystemExit, "OnInit returned false, exiting...");
|
||||
}
|
||||
error:
|
||||
wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Function to test if the Display (or whatever is the platform equivallent)
|
||||
// can be connected to. This is accessable from wxPython as a staticmethod of
|
||||
// wx.App called IsDisplayAvailable().
|
||||
bool wxPyApp::IsDisplayAvailable()
|
||||
{
|
||||
#ifdef __WXGTK__
|
||||
Display* display;
|
||||
display = XOpenDisplay(NULL);
|
||||
if (display == NULL)
|
||||
return false;
|
||||
XCloseDisplay(display);
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef __WXMAC__
|
||||
// This is adapted from Python's Mac/Modules/MacOS.c in the
|
||||
// MacOS_WMAvailable function.
|
||||
bool rv;
|
||||
ProcessSerialNumber psn;
|
||||
|
||||
/*
|
||||
** This is a fairly innocuous call to make if we don't have a window
|
||||
** manager, or if we have no permission to talk to it. It will print
|
||||
** a message on stderr, but at least it won't abort the process.
|
||||
** It appears the function caches the result itself, and it's cheap, so
|
||||
** no need for us to cache.
|
||||
*/
|
||||
#ifdef kCGNullDirectDisplay
|
||||
/* On 10.1 CGMainDisplayID() isn't available, and
|
||||
** kCGNullDirectDisplay isn't defined.
|
||||
*/
|
||||
if (CGMainDisplayID() == 0) {
|
||||
rv = false;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Also foreground the application on the first call as a side-effect.
|
||||
if (GetCurrentProcess(&psn) < 0 || SetFrontProcess(&psn) < 0) {
|
||||
rv = false;
|
||||
} else {
|
||||
rv = true;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
#endif
|
||||
|
||||
#ifdef __WXMSW__
|
||||
// TODO...
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
wxPyApp* wxGetApp()
|
||||
{
|
||||
return wxPyApp::ms_appInstance;
|
||||
}
|
||||
275
src/app_ex.py
Normal file
275
src/app_ex.py
Normal file
@@ -0,0 +1,275 @@
|
||||
|
||||
class PyOnDemandOutputWindow:
|
||||
"""
|
||||
A class that can be used for redirecting Python's stdout and
|
||||
stderr streams. It will do nothing until something is wrriten to
|
||||
the stream at which point it will create a Frame with a text area
|
||||
and write the text there.
|
||||
"""
|
||||
def __init__(self, title="wxPython: stdout/stderr"):
|
||||
self.frame = None
|
||||
self.title = title
|
||||
self.pos = wx.DefaultPosition
|
||||
self.size = (450, 300)
|
||||
self.parent = None
|
||||
|
||||
def SetParent(self, parent):
|
||||
"""Set the window to be used as the popup Frame's parent."""
|
||||
self.parent = parent
|
||||
|
||||
|
||||
def CreateOutputWindow(self, st):
|
||||
self.frame = wx.Frame(self.parent, -1, self.title, self.pos, self.size,
|
||||
style=wx.DEFAULT_FRAME_STYLE)
|
||||
self.text = wx.TextCtrl(self.frame, -1, "",
|
||||
style=wx.TE_MULTILINE|wx.TE_READONLY)
|
||||
self.text.AppendText(st)
|
||||
self.frame.Show(True)
|
||||
self.frame.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
|
||||
|
||||
|
||||
def OnCloseWindow(self, event):
|
||||
if self.frame is not None:
|
||||
self.frame.Destroy()
|
||||
self.frame = None
|
||||
self.text = None
|
||||
self.parent = None
|
||||
|
||||
|
||||
# These methods provide the file-like output behaviour.
|
||||
def write(self, text):
|
||||
"""
|
||||
Create the output window if needed and write the string to it.
|
||||
If not called in the context of the gui thread then uses
|
||||
CallAfter to do the work there.
|
||||
"""
|
||||
if self.frame is None:
|
||||
if not wx.Thread.IsMain():
|
||||
wx.CallAfter(self.CreateOutputWindow, text)
|
||||
else:
|
||||
self.CreateOutputWindow(text)
|
||||
else:
|
||||
if not wx.Thread.IsMain():
|
||||
wx.CallAfter(self.text.AppendText, text)
|
||||
else:
|
||||
self.text.AppendText(text)
|
||||
|
||||
|
||||
def close(self):
|
||||
if self.frame is not None:
|
||||
wx.CallAfter(self.frame.Close)
|
||||
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class App(wx.PyApp):
|
||||
"""
|
||||
The ``wx.App`` class represents the application and is used to:
|
||||
|
||||
* bootstrap the wxPython system and initialize the underlying
|
||||
gui toolkit
|
||||
* set and get application-wide properties
|
||||
* implement the native windowing system main message or event loop,
|
||||
and to dispatch events to window instances
|
||||
* etc.
|
||||
|
||||
Every wx application must have a single ``wx.App`` instance, and all
|
||||
creation of UI objects should be delayed until after the ``wx.App`` object
|
||||
has been created in order to ensure that the gui platform and wxWidgets
|
||||
have been fully initialized.
|
||||
|
||||
Normally you would derive from this class and implement an ``OnInit``
|
||||
method that creates a frame and then calls ``self.SetTopWindow(frame)``,
|
||||
however ``wx.App`` is also usable on it's own without derivation.
|
||||
"""
|
||||
|
||||
outputWindowClass = PyOnDemandOutputWindow
|
||||
|
||||
def __init__(self,
|
||||
redirect=False,
|
||||
filename=None,
|
||||
useBestVisual=False,
|
||||
clearSigInt=True):
|
||||
"""
|
||||
Construct a ``wx.App`` object.
|
||||
|
||||
:param redirect: Should ``sys.stdout`` and ``sys.stderr`` be
|
||||
redirected? Defaults to False. If ``filename`` is None
|
||||
then output will be redirected to a window that pops up
|
||||
as needed. (You can control what kind of window is created
|
||||
for the output by resetting the class variable
|
||||
``outputWindowClass`` to a class of your choosing.)
|
||||
|
||||
:param filename: The name of a file to redirect output to, if
|
||||
redirect is True.
|
||||
|
||||
:param useBestVisual: Should the app try to use the best
|
||||
available visual provided by the system (only relevant on
|
||||
systems that have more than one visual.) This parameter
|
||||
must be used instead of calling `SetUseBestVisual` later
|
||||
on because it must be set before the underlying GUI
|
||||
toolkit is initialized.
|
||||
|
||||
:param clearSigInt: Should SIGINT be cleared? This allows the
|
||||
app to terminate upon a Ctrl-C in the console like other
|
||||
GUI apps will.
|
||||
|
||||
:note: You should override OnInit to do applicaition
|
||||
initialization to ensure that the system, toolkit and
|
||||
wxWidgets are fully initialized.
|
||||
"""
|
||||
|
||||
wx.PyApp.__init__(self)
|
||||
|
||||
# make sure we can create a GUI
|
||||
if not self.IsDisplayAvailable():
|
||||
|
||||
if wx.Port == "__WXMAC__":
|
||||
msg = """This program needs access to the screen.
|
||||
Please run with a Framework build of python, and only when you are
|
||||
logged in on the main display of your Mac."""
|
||||
|
||||
elif wx.Port == "__WXGTK__":
|
||||
msg ="Unable to access the X Display, is $DISPLAY set properly?"
|
||||
|
||||
else:
|
||||
msg = "Unable to create GUI"
|
||||
# TODO: more description is needed for wxMSW...
|
||||
|
||||
raise SystemExit(msg)
|
||||
|
||||
# This has to be done before OnInit
|
||||
self.SetUseBestVisual(useBestVisual)
|
||||
|
||||
# Set the default handler for SIGINT. This fixes a problem
|
||||
# where if Ctrl-C is pressed in the console that started this
|
||||
# app then it will not appear to do anything, (not even send
|
||||
# KeyboardInterrupt???) but will later segfault on exit. By
|
||||
# setting the default handler then the app will exit, as
|
||||
# expected (depending on platform.)
|
||||
if clearSigInt:
|
||||
try:
|
||||
import signal
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Save and redirect the stdio to a window?
|
||||
self.stdioWin = None
|
||||
self.saveStdio = (_sys.stdout, _sys.stderr)
|
||||
if redirect:
|
||||
self.RedirectStdio(filename)
|
||||
|
||||
## # Use Python's install prefix as the default
|
||||
## wx.StandardPaths.Get().SetInstallPrefix(_sys.prefix)
|
||||
|
||||
## # Until the new native control for wxMac is up to par, still use the generic one.
|
||||
## wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", 1)
|
||||
|
||||
# This finishes the initialization of wxWindows and then calls
|
||||
# the OnInit that should be present in the derived class
|
||||
self._BootstrapApp()
|
||||
|
||||
|
||||
def OnPreInit(self):
|
||||
"""
|
||||
Things that must be done after _BootstrapApp has done its
|
||||
thing, but would be nice if they were already done by the time
|
||||
that OnInit is called.
|
||||
"""
|
||||
print 'OnPreInit'
|
||||
## wx.StockGDI._initStockObjects()
|
||||
|
||||
|
||||
def __del__(self):
|
||||
self.RestoreStdio() # Just in case the MainLoop was overridden
|
||||
|
||||
def Destroy(self):
|
||||
## self.this.own(False)
|
||||
wx.PyApp.Destroy(self)
|
||||
|
||||
def SetTopWindow(self, frame):
|
||||
"""Set the \"main\" top level window"""
|
||||
if self.stdioWin:
|
||||
self.stdioWin.SetParent(frame)
|
||||
wx.PyApp.SetTopWindow(self, frame)
|
||||
|
||||
|
||||
def MainLoop(self):
|
||||
"""Execute the main GUI event loop"""
|
||||
wx.PyApp.MainLoop(self)
|
||||
self.RestoreStdio()
|
||||
|
||||
|
||||
def RedirectStdio(self, filename=None):
|
||||
"""Redirect sys.stdout and sys.stderr to a file or a popup window."""
|
||||
if filename:
|
||||
_sys.stdout = _sys.stderr = open(filename, 'a')
|
||||
else:
|
||||
self.stdioWin = self.outputWindowClass()
|
||||
_sys.stdout = _sys.stderr = self.stdioWin
|
||||
|
||||
|
||||
def RestoreStdio(self):
|
||||
try:
|
||||
_sys.stdout, _sys.stderr = self.saveStdio
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def SetOutputWindowAttributes(self, title=None, pos=None, size=None):
|
||||
"""
|
||||
Set the title, position and/or size of the output window if
|
||||
the stdio has been redirected. This should be called before
|
||||
any output would cause the output window to be created.
|
||||
"""
|
||||
if self.stdioWin:
|
||||
if title is not None:
|
||||
self.stdioWin.title = title
|
||||
if pos is not None:
|
||||
self.stdioWin.pos = pos
|
||||
if size is not None:
|
||||
self.stdioWin.size = size
|
||||
|
||||
## #----------------------------------------------------------------------------
|
||||
|
||||
## # TODO: Move this someplace else?
|
||||
## def deprecated(func):
|
||||
## def new_func(*args, **kwargs):
|
||||
## import warnings
|
||||
## warnings.warn("Call to deprecated function %s." % func.__name__,
|
||||
## category=DeprecationWarning)
|
||||
## return func(*args, **kwargs)
|
||||
## new_func.__name__ = func.__name__
|
||||
## new_func.__doc__ = func.__doc__
|
||||
## new_func.__dict__.update(func.__dict__)
|
||||
## return new_func
|
||||
|
||||
|
||||
## @deprecated
|
||||
## class PySimpleApp(App):
|
||||
## """
|
||||
## This class is deprecated. Please use wx.App isntead.
|
||||
## """
|
||||
## def __init__(self, *args, **kw):
|
||||
## App.__init__(self, *args, **kw)
|
||||
|
||||
|
||||
## #----------------------------------------------------------------------------
|
||||
## # DO NOT hold any other references to this object. This is how we
|
||||
## # know when to cleanup system resources that wxWidgets is holding. When
|
||||
## # the sys module is unloaded, the refcount on sys.__wxPythonCleanup
|
||||
## # goes to zero and it calls the wx.App_CleanUp function.
|
||||
|
||||
## #class __wxPyCleanup:
|
||||
## #def __init__(self):
|
||||
## #self.cleanup = _core_.App_CleanUp
|
||||
## #def __del__(self):
|
||||
## #self.cleanup()
|
||||
|
||||
## #_sys.__wxPythonCleanup = __wxPyCleanup()
|
||||
219
src/core_ex.py
Normal file
219
src/core_ex.py
Normal file
@@ -0,0 +1,219 @@
|
||||
|
||||
# Load version numbers from __version__... Ensure that major and minor
|
||||
# versions are the same for both wxPython and wxWidgets.
|
||||
|
||||
from __version__ import *
|
||||
__version__ = VERSION_STRING
|
||||
import _core
|
||||
assert MAJOR_VERSION == _core.MAJOR_VERSION, "wxPython/wxWidgets version mismatch"
|
||||
assert MINOR_VERSION == _core.MINOR_VERSION, "wxPython/wxWidgets version mismatch"
|
||||
if RELEASE_NUMBER != _core.RELEASE_NUMBER:
|
||||
import warnings
|
||||
warnings.warn("wxPython/wxWidgets release number mismatch")
|
||||
del _core
|
||||
|
||||
|
||||
def version():
|
||||
"""Returns a string containing version and port info"""
|
||||
if wx.Platform == '__WXMSW__':
|
||||
port = 'msw'
|
||||
elif wx.Platform == '__WXMAC__':
|
||||
if 'wxOSX-carbon' in wx.PlatformInfo:
|
||||
port = 'osx-carbon'
|
||||
else:
|
||||
port = 'osx-cocoa'
|
||||
elif wx.Platform == '__WXGTK__':
|
||||
port = 'gtk'
|
||||
if 'gtk2' in wx.PlatformInfo:
|
||||
port = 'gtk2'
|
||||
else:
|
||||
port = '?'
|
||||
return "%s %s" % (wx.VERSION_STRING, port)
|
||||
|
||||
|
||||
## #----------------------------------------------------------------------------
|
||||
|
||||
## class PyDeadObjectError(AttributeError):
|
||||
## pass
|
||||
|
||||
## class _wxPyDeadObject(object):
|
||||
## """
|
||||
## Instances of wx objects that are OOR capable will have their __class__
|
||||
## changed to this class when the C++ object is deleted. This should help
|
||||
## prevent crashes due to referencing a bogus C++ pointer.
|
||||
## """
|
||||
## reprStr = "wxPython wrapper for DELETED %s object! (The C++ object no longer exists.)"
|
||||
## attrStr = "The C++ part of the %s object has been deleted, attribute access no longer allowed."
|
||||
|
||||
## def __repr__(self):
|
||||
## if not hasattr(self, "_name"):
|
||||
## self._name = "[unknown]"
|
||||
## return self.reprStr % self._name
|
||||
|
||||
## def __getattr__(self, *args):
|
||||
## if not hasattr(self, "_name"):
|
||||
## self._name = "[unknown]"
|
||||
## raise PyDeadObjectError(self.attrStr % self._name)
|
||||
|
||||
## def __nonzero__(self):
|
||||
## return 0
|
||||
|
||||
|
||||
|
||||
## class PyUnbornObjectError(AttributeError):
|
||||
## pass
|
||||
|
||||
## class _wxPyUnbornObject(object):
|
||||
## """
|
||||
## Some stock objects are created when the wx._core module is
|
||||
## imported, but their C++ instance is not created until the wx.App
|
||||
## object is created and initialized. These object instances will
|
||||
## temporarily have their __class__ changed to this class so an
|
||||
## exception will be raised if they are used before the C++ instance
|
||||
## is ready.
|
||||
## """
|
||||
|
||||
## reprStr = "wxPython wrapper for UNBORN object! (The C++ object is not initialized yet.)"
|
||||
## attrStr = "The C++ part of this object has not been initialized, attribute access not allowed."
|
||||
|
||||
## def __repr__(self):
|
||||
## #if not hasattr(self, "_name"):
|
||||
## # self._name = "[unknown]"
|
||||
## return self.reprStr #% self._name
|
||||
|
||||
## def __getattr__(self, *args):
|
||||
## #if not hasattr(self, "_name"):
|
||||
## # self._name = "[unknown]"
|
||||
## raise PyUnbornObjectError(self.attrStr) # % self._name )
|
||||
|
||||
## def __nonzero__(self):
|
||||
## return 0
|
||||
|
||||
|
||||
## #----------------------------------------------------------------------------
|
||||
|
||||
## def CallAfter(callable, *args, **kw):
|
||||
## """
|
||||
## Call the specified function after the current and pending event
|
||||
## handlers have been completed. This is also good for making GUI
|
||||
## method calls from non-GUI threads. Any extra positional or
|
||||
## keyword args are passed on to the callable when it is called.
|
||||
|
||||
## :see: `wx.CallLater`
|
||||
## """
|
||||
## app = wx.GetApp()
|
||||
## assert app is not None, 'No wx.App created yet'
|
||||
|
||||
## if not hasattr(app, "_CallAfterId"):
|
||||
## app._CallAfterId = wx.NewEventType()
|
||||
## app.Connect(-1, -1, app._CallAfterId,
|
||||
## lambda event: event.callable(*event.args, **event.kw) )
|
||||
## evt = wx.PyEvent()
|
||||
## evt.SetEventType(app._CallAfterId)
|
||||
## evt.callable = callable
|
||||
## evt.args = args
|
||||
## evt.kw = kw
|
||||
## wx.PostEvent(app, evt)
|
||||
|
||||
## #----------------------------------------------------------------------------
|
||||
|
||||
|
||||
## class CallLater:
|
||||
## """
|
||||
## A convenience class for `wx.Timer`, that calls the given callable
|
||||
## object once after the given amount of milliseconds, passing any
|
||||
## positional or keyword args. The return value of the callable is
|
||||
## availbale after it has been run with the `GetResult` method.
|
||||
|
||||
## If you don't need to get the return value or restart the timer
|
||||
## then there is no need to hold a reference to this object. It will
|
||||
## hold a reference to itself while the timer is running (the timer
|
||||
## has a reference to self.Notify) but the cycle will be broken when
|
||||
## the timer completes, automatically cleaning up the wx.CallLater
|
||||
## object.
|
||||
|
||||
## :see: `wx.CallAfter`
|
||||
## """
|
||||
## def __init__(self, millis, callable, *args, **kwargs):
|
||||
## self.millis = millis
|
||||
## self.callable = callable
|
||||
## self.SetArgs(*args, **kwargs)
|
||||
## self.runCount = 0
|
||||
## self.running = False
|
||||
## self.hasRun = False
|
||||
## self.result = None
|
||||
## self.timer = None
|
||||
## self.Start()
|
||||
|
||||
## def __del__(self):
|
||||
## self.Stop()
|
||||
|
||||
|
||||
## def Start(self, millis=None, *args, **kwargs):
|
||||
## """
|
||||
## (Re)start the timer
|
||||
## """
|
||||
## self.hasRun = False
|
||||
## if millis is not None:
|
||||
## self.millis = millis
|
||||
## if args or kwargs:
|
||||
## self.SetArgs(*args, **kwargs)
|
||||
## self.Stop()
|
||||
## self.timer = wx.PyTimer(self.Notify)
|
||||
## self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
|
||||
## self.running = True
|
||||
## Restart = Start
|
||||
|
||||
|
||||
## def Stop(self):
|
||||
## """
|
||||
## Stop and destroy the timer.
|
||||
## """
|
||||
## if self.timer is not None:
|
||||
## self.timer.Stop()
|
||||
## self.timer = None
|
||||
|
||||
|
||||
## def GetInterval(self):
|
||||
## if self.timer is not None:
|
||||
## return self.timer.GetInterval()
|
||||
## else:
|
||||
## return 0
|
||||
|
||||
|
||||
## def IsRunning(self):
|
||||
## return self.timer is not None and self.timer.IsRunning()
|
||||
|
||||
|
||||
## def SetArgs(self, *args, **kwargs):
|
||||
## """
|
||||
## (Re)set the args passed to the callable object. This is
|
||||
## useful in conjunction with Restart if you want to schedule a
|
||||
## new call to the same callable object but with different
|
||||
## parameters.
|
||||
## """
|
||||
## self.args = args
|
||||
## self.kwargs = kwargs
|
||||
|
||||
|
||||
## def HasRun(self):
|
||||
## return self.hasRun
|
||||
|
||||
## def GetResult(self):
|
||||
## return self.result
|
||||
|
||||
## def Notify(self):
|
||||
## """
|
||||
## The timer has expired so call the callable.
|
||||
## """
|
||||
## if self.callable and getattr(self.callable, 'im_self', True):
|
||||
## self.runCount += 1
|
||||
## self.running = False
|
||||
## self.result = self.callable(*self.args, **self.kwargs)
|
||||
## self.hasRun = True
|
||||
## if not self.running:
|
||||
## # if it wasn't restarted, then cleanup
|
||||
## wx.CallAfter(self.Stop)
|
||||
|
||||
## Interval = property(GetInterval)
|
||||
## Result = property(GetResult)
|
||||
26
src/core_utils.cpp
Normal file
26
src/core_utils.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
//--------------------------------------------------------------------------
|
||||
// Name: src/core_utils.cpp
|
||||
// Purpose: Various utility and helper functions used by the _core
|
||||
// wxPython(phoenix) extension module that are easier to maintain
|
||||
// here than in the etg scripts that use them.
|
||||
//
|
||||
// Author: Robin Dunn
|
||||
//
|
||||
// Created: 24-Nov-2010
|
||||
// RCS-ID: $Id: $
|
||||
// Copyright: (c) 2010 by Total Control Software
|
||||
// Licence: wxWindows license
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
#undef DEBUG
|
||||
#include <Python.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
|
||||
// Nothing is here yet, but there probably will be...
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
17
src/core_utils.h
Normal file
17
src/core_utils.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//--------------------------------------------------------------------------
|
||||
// Name: src/core_utils.h
|
||||
// Purpose: Various utility and helper functions used by the _core
|
||||
// wxPython(phoenix) extension module that are easier to maintain
|
||||
// here than in the etg scripts that use them.
|
||||
//
|
||||
// Author: Robin Dunn
|
||||
//
|
||||
// Created: 24-Nov-2010
|
||||
// RCS-ID: $Id: $
|
||||
// Copyright: (c) 2010 by Total Control Software
|
||||
// Licence: wxWindows license
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Nothing is here yet, but there probably will be...
|
||||
@@ -14,31 +14,27 @@
|
||||
// at all, so it will be mapped to and from Python Unicode objects using the
|
||||
// code snippets below.
|
||||
|
||||
// NOTE: Currently we assume that string objects are encoding in utf-8. Decide if we
|
||||
// want to do this or to use the default encoding for the locale like the old
|
||||
// wxPython does.
|
||||
// NOTE: Currently we assume that string objects are encoding in utf-8.
|
||||
|
||||
%MappedType wxString
|
||||
{
|
||||
// Code to test a PyObject for compatibility and to convert from a
|
||||
// PyObject to a wxString
|
||||
%ConvertToTypeCode
|
||||
// just check the type?
|
||||
// Code to test a PyObject for compatibility with wxString
|
||||
if (!sipIsErr) {
|
||||
if (PyString_Check(sipPy) || PyUnicode_Check(sipPy))
|
||||
return 1;
|
||||
return 0;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
// Or do the conversion
|
||||
#if wxUSE_UNICODE_WCHAR
|
||||
// wxString will contain wide chars (wchar_t)
|
||||
|
||||
// Code to convert a compatible PyObject to a wxString
|
||||
PyObject* uni = sipPy;
|
||||
if (PyString_Check(sipPy)) {
|
||||
// if it's a string object convert it to unicode first
|
||||
uni = PyUnicode_FromEncodedObject(sipPy,
|
||||
"utf-8", /*wxPyDefaultEncoding*/
|
||||
"strict");
|
||||
if (PyErr_Occurred()) return 0;
|
||||
// if it's a string object convert it to unicode first, assuming utf-8
|
||||
uni = PyUnicode_FromEncodedObject(sipPy, "utf-8", "strict");
|
||||
if (PyErr_Occurred()) {
|
||||
*sipIsErr = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*sipCppPtr = new wxString();
|
||||
size_t len = PyUnicode_GET_SIZE(uni);
|
||||
@@ -49,37 +45,24 @@
|
||||
if (PyString_Check(sipPy))
|
||||
Py_DECREF(uni); // release the temporary Unicode object we created
|
||||
return sipGetState(sipTransferObj);
|
||||
#else
|
||||
// wxString will contain a utf-8 encoded byte string. If source is
|
||||
// already a string then use it as-is, (assuming utf-8) otherwise
|
||||
// the Unicode object to utf-8 and use the converted value.
|
||||
char* tmpPtr; Py_ssize_t tmpSize;
|
||||
PyObject* str = NULL;
|
||||
//PyObject* uni = NULL;
|
||||
if (PyString_Check(sipPy) /*&& wxPyDefaultEncodingIsUTF8 */) {
|
||||
PyString_AsStringAndSize(sipPy, &tmpPtr, &tmpSize);
|
||||
}
|
||||
//else if (PyString_Check(sipPy)) {
|
||||
// uni = PyUnicode_FromEncodedObject(sipPy, wxPyDefaultEncoding, "strict");
|
||||
// if (PyErr_Occurred()) return NULL;
|
||||
// str = PyUnicode_AsUTF8String(uni);
|
||||
// PyString_AsStringAndSize(sipPy, &tmpPtr, &tmpSize);
|
||||
//}
|
||||
else {
|
||||
str = PyUnicode_AsUTF8String(sipPy);
|
||||
PyString_AsStringAndSize(str, &tmpPtr, &tmpSize);
|
||||
}
|
||||
*sipCppPtr = new wxString(tmpPtr, tmpSize);
|
||||
Py_XDECREF(str);
|
||||
//Py_XDECREF(uni);
|
||||
return sipGetState(sipTransferObj);
|
||||
#endif
|
||||
%End
|
||||
|
||||
|
||||
// Code to convert a wxString to a PyObject
|
||||
%ConvertFromTypeCode
|
||||
return sipBuildResult(NULL, "G", sipCpp->c_str(), sipCpp->length());
|
||||
// Code to convert a wxString to a Python Unicode object.
|
||||
return PyUnicode_FromWideChar(sipCpp->wc_str(), sipCpp->length());
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Used just for testing the MappedType code
|
||||
%ModuleCode
|
||||
wxString testStringTypemap(const wxString& str)
|
||||
{
|
||||
wxString local = str;
|
||||
return local;
|
||||
}
|
||||
%End
|
||||
wxString testStringTypemap(const wxString& str);
|
||||
|
||||
104
src/wxpy_utils.sip
Normal file
104
src/wxpy_utils.sip
Normal file
@@ -0,0 +1,104 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wxpy_utils.sip
|
||||
// Purpose: Some utility functions and such that can be used in other
|
||||
// snippets of C++ code to help reduce complexity, etc.
|
||||
//
|
||||
// Author: Robin Dunn
|
||||
//
|
||||
// Created: 19-Nov-2010
|
||||
// Copyright: (c) 2010 by Total Control Software
|
||||
// Licence: wxWindows license
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
%ModuleHeaderCode
|
||||
|
||||
// Convert a PyObject to a wxString
|
||||
wxString Py2wxString(PyObject* source);
|
||||
|
||||
// Raise NotImplemented exceptions
|
||||
inline void wxPyRaiseNotImplemented() {
|
||||
PyErr_SetNone(PyExc_NotImplementedError);
|
||||
}
|
||||
|
||||
inline void wxPyRaiseNotImplementedMsg(const char* msg) {
|
||||
PyErr_SetString(PyExc_NotImplementedError, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef PyGILState_STATE wxPyBlock_t;
|
||||
|
||||
// Calls from Python to wxWindows code are wrapped in calls to these
|
||||
// functions:
|
||||
|
||||
inline PyThreadState* wxPyBeginAllowThreads() {
|
||||
PyThreadState* saved = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS;
|
||||
return saved;
|
||||
}
|
||||
|
||||
inline void wxPyEndAllowThreads(PyThreadState* saved) {
|
||||
PyEval_RestoreThread(saved); // Py_END_ALLOW_THREADS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Calls from wxWindows back to Python code, or even any PyObject
|
||||
// manipulations, PyDECREF's and etc. are wrapped in calls to these functions:
|
||||
|
||||
inline wxPyBlock_t wxPyBeginBlockThreads() {
|
||||
if (! Py_IsInitialized()) {
|
||||
return (wxPyBlock_t)0;
|
||||
}
|
||||
PyGILState_STATE state = PyGILState_Ensure();
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
inline void wxPyEndBlockThreads(wxPyBlock_t blocked) {
|
||||
if (! Py_IsInitialized()) {
|
||||
return;
|
||||
}
|
||||
PyGILState_Release(blocked);
|
||||
}
|
||||
|
||||
%End
|
||||
|
||||
|
||||
|
||||
%ModuleCode
|
||||
// Various wxPython helper/utility functions
|
||||
|
||||
// See also the wxString MappedType. This code is similar, but doesn't
|
||||
// allocate a new wxString instance on the heap, is able to convert
|
||||
// non-string/unicode objects to unicode, and won't raise exceptions
|
||||
wxString Py2wxString(PyObject* source)
|
||||
{
|
||||
PyObject* uni = source;
|
||||
if (PyString_Check(source)) {
|
||||
// if it's a string object convert it to unicode first, assumes utf-8
|
||||
uni = PyUnicode_FromEncodedObject(source, "utf-8", "strict");
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
return wxEmptyString;
|
||||
}
|
||||
}
|
||||
else if (!PyUnicode_Check(source)) {
|
||||
uni = PyObject_Unicode(source);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
return wxEmptyString;
|
||||
}
|
||||
}
|
||||
|
||||
wxString target;
|
||||
size_t len = PyUnicode_GET_SIZE(uni);
|
||||
if (len) {
|
||||
PyUnicode_AsWideChar((PyUnicodeObject*)uni,
|
||||
wxStringBuffer(target, len), len);
|
||||
}
|
||||
if (!PyUnicode_Check(source))
|
||||
Py_DECREF(uni); // release the temporary Unicode object we created
|
||||
return target;
|
||||
}
|
||||
%End
|
||||
28
unittests/test_app.py
Normal file
28
unittests/test_app.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import unittest2
|
||||
import wxPhoenix as wx
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class App(unittest2.TestCase):
|
||||
|
||||
def test_App(self):
|
||||
app = wx.App()
|
||||
|
||||
def test_App_OnInit(self):
|
||||
|
||||
class MyApp(wx.App):
|
||||
def OnInit(self):
|
||||
self.onInit_called = True
|
||||
return True
|
||||
|
||||
app = MyApp()
|
||||
self.assertTrue(app.onInit_called)
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
||||
55
unittests/test_colour.py
Normal file
55
unittests/test_colour.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import unittest2
|
||||
import wxPhoenix as wx
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class Colour(unittest2.TestCase):
|
||||
def setUp(self):
|
||||
if hasattr(wx, 'InitializeStockLists'):
|
||||
wx.InitializeStockLists() # switch to wx.App once we have that class working
|
||||
|
||||
def test_default_ctor(self):
|
||||
c = wx.Colour()
|
||||
self.assertTrue(not c.IsOk())
|
||||
self.assertTrue(c.Get() == (-1,-1,-1,255))
|
||||
|
||||
def test_rgb_ctor(self):
|
||||
c = wx.Colour(1,2,3)
|
||||
self.assertTrue(c.Get(False) == (1,2,3))
|
||||
|
||||
def test_rgba_ctor(self):
|
||||
c = wx.Colour(1,2,3,4)
|
||||
self.assertTrue(c.Get() == (1,2,3,4))
|
||||
|
||||
def test_copy_ctor(self):
|
||||
c1 = wx.Colour(1,2,3,4)
|
||||
c2 = wx.Colour(c1)
|
||||
self.assertTrue(c1 == c2)
|
||||
self.assertTrue(c1 is not c2)
|
||||
self.assertTrue(c1.Get() == c2.Get())
|
||||
|
||||
|
||||
if hasattr(wx, 'testColourTypeMap'):
|
||||
def test_ColourTypemaps(self):
|
||||
c = wx.testColourTypeMap('red')
|
||||
self.assertTrue(c.Get() == (0xff, 0, 0, 0xff))
|
||||
c = wx.testColourTypeMap('Blue:80')
|
||||
self.assertTrue(c.Get() == (0, 0, 0xff, 0x80))
|
||||
c = wx.testColourTypeMap('#112233')
|
||||
self.assertTrue(c.Get() == (0x11, 0x22, 0x33, 0xff))
|
||||
c = wx.testColourTypeMap('#11223344')
|
||||
self.assertTrue(c.Get() == (0x11, 0x22, 0x33, 0x44))
|
||||
c = wx.testColourTypeMap(None)
|
||||
self.assertTrue(c.Get() == (-1, -1, -1, 0xff))
|
||||
c = wx.testColourTypeMap( (1,2,3) )
|
||||
self.assertTrue(c.Get() == (1, 2, 3, 0xff))
|
||||
c = wx.testColourTypeMap( (1,2,3,4) )
|
||||
self.assertTrue(c.Get() == (1, 2, 3, 4))
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
||||
@@ -1,5 +1,5 @@
|
||||
import unittest2
|
||||
import wx
|
||||
import wxPhoenix as wx
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import unittest2
|
||||
import wx
|
||||
import wxPhoenix as wx
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import unittest2
|
||||
import wx
|
||||
import wxPhoenix as wx
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import unittest2
|
||||
import wx
|
||||
import wxPhoenix as wx
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import unittest2
|
||||
import wx
|
||||
import wxPhoenix as wx
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
62
unittests/test_string.py
Normal file
62
unittests/test_string.py
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
import unittest2
|
||||
import wxPhoenix as wx
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class String(unittest2.TestCase):
|
||||
|
||||
if hasattr(wx, 'testStringTypemap'):
|
||||
def test_StringTypemaps(self):
|
||||
utf = '\xc3\xa9l\xc3\xa9phant' # utf-8 string
|
||||
uni = utf.decode('utf-8') # convert to unicode
|
||||
iso = uni.encode('iso-8859-1') # make a string with a different encoding
|
||||
|
||||
|
||||
# wx.testStringTypemap() will accept a parameter that is a Unicode object
|
||||
# or an 'ascii' or 'utf-8' string object, which will then be converted to
|
||||
# a wxString. The return value is a Unicode object that has been
|
||||
# converted from a wxString that is a copy of the wxString created for
|
||||
# the parameter.
|
||||
|
||||
# ascii
|
||||
result = wx.testStringTypemap('hello')
|
||||
self.assertTrue(type(result) == unicode)
|
||||
self.assertTrue(result == u'hello')
|
||||
|
||||
# unicode should pass through unmodified
|
||||
result = wx.testStringTypemap(uni)
|
||||
self.assertTrue(result == uni)
|
||||
|
||||
# utf-8 is converted
|
||||
result = wx.testStringTypemap(utf)
|
||||
self.assertTrue(result == uni)
|
||||
|
||||
# can't auto-convert this
|
||||
with self.assertRaises(UnicodeDecodeError):
|
||||
result = wx.testStringTypemap(iso)
|
||||
|
||||
# utf-16-be
|
||||
val = "\x00\xe9\x00l\x00\xe9\x00p\x00h\x00a\x00n\x00t"
|
||||
with self.assertRaises(UnicodeDecodeError):
|
||||
result = wx.testStringTypemap(val)
|
||||
result = wx.testStringTypemap( val.decode('utf-16-be'))
|
||||
self.assertTrue(result == uni)
|
||||
|
||||
# utf-32-be
|
||||
val = "\x00\x00\x00\xe9\x00\x00\x00l\x00\x00\x00\xe9\x00\x00\x00p\x00\x00\x00h\x00\x00\x00a\x00\x00\x00n\x00\x00\x00t"
|
||||
with self.assertRaises(UnicodeDecodeError):
|
||||
result = wx.testStringTypemap(val)
|
||||
result = wx.testStringTypemap(val.decode('utf-32-be'))
|
||||
self.assertTrue(result == uni)
|
||||
|
||||
# utf-8 with BOM
|
||||
val = "\xef\xbb\xbfHello"
|
||||
result = wx.testStringTypemap(val)
|
||||
self.assertTrue(result == u'\ufeffHello')
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
||||
Reference in New Issue
Block a user