diff --git a/b b/b new file mode 100755 index 00000000..b7a05adf --- /dev/null +++ b/b @@ -0,0 +1,17 @@ +#!/bin/bash + +##set -o xtrace + +PYVER=2.6 +PYVER2=26 + + +if [ "$OSTYPE" = "cygwin" ]; then + $TOOLS/python$PYVER2/python.exe -u build.py "$@" +else + PATH=/usr/local/bin:$PATH + PYTHON=`which python$PYVER` + $PYTHON -u build.py "$@" +fi + +exit $? diff --git a/build.py b/build.py index 04c8e38c..3c4598c3 100755 --- a/build.py +++ b/build.py @@ -10,6 +10,7 @@ import sys import os import re import glob +import shutil import subprocess import optparse @@ -26,7 +27,11 @@ version2 = "%d.%d" % (version.VER_MAJOR, version.VER_MINOR) version3 = "%d.%d.%d" % (version.VER_MAJOR, version.VER_MINOR, version.VER_RELEASE) version2_nodot = version2.replace(".", "") version3_nodot = version3.replace(".", "") +unstable_series = (version.VER_MINOR % 2) == 1 # is the minor version odd or even +isWindows = sys.platform.startswith('win') +isDarwin = sys.platform == "darwin" + #--------------------------------------------------------------------------- def usage(): @@ -34,23 +39,24 @@ def usage(): Usage: ./build.py [command(s)] [options] Commands: - N.N NN Major.Minor version number of the Python to use to run - the other commands. Default is 2.6 - dox Run Doxygen to produce the XML file used by ETG scripts - doxhtml Run Doxygen to create the HTML documetation for wx - touch 'touch' the etg files so they will all get run in the - next build - etg Run the ETG scripts that are out of date to update their - SIP files - test Run the unit test suite + N.N NN Major.Minor version number of the Python to use to run + the other commands. Default is 2.6 + dox Run Doxygen to produce the XML file used by ETG scripts + doxhtml Run Doxygen to create the HTML documetation for wx + touch 'touch' the etg files so they will all get run in the + next build + etg Run the ETG scripts that are out of date to update their + SIP files + sip Run sip + test Run the unit test suite - build_wx Do the wxWidgets part of the build - build_py Build wxPython only - build Builds both wxWidgets and wxPython. + build_wx Do the wxWidgets part of the build + build_py Build wxPython only + build Build both wxWidgets and wxPython. - clean_wx - clean_py - cleanall + clean_wx Clean the wx parts of the build + clean_py Clean the wxPython parts of the build + cleanall Clean both wx and wxPython, and a little extra scrubbing """ parser = makeOptionParser() parser.print_help() @@ -74,7 +80,7 @@ def main(args): while commands: cmd = commands[0] commands = commands[1:] - if cmd in ['dox', 'doxhtml', 'etg', 'touch', 'test', + if cmd in ['dox', 'doxhtml', 'etg', 'sip', 'touch', 'test', 'build_wx', 'build_py', 'build', 'clean_wx', 'clean_py', 'cleanall']: function = globals()[cmd] @@ -115,10 +121,6 @@ def runcmd(cmd, getOutput=False, echoCmd=True): def setPythonVersion(args): - # TODO: Should we default to the python that is running this script if a - # version was not given? Probably YES on Windows, but only if TOOLS is not - # set in the environment. - # TODO: Should we have a --option for specifying the path to the python # executable that should be used? @@ -138,28 +140,48 @@ def setPythonVersion(args): break PYTHON = 'python%s' % PYVER - if sys.platform.startswith('win'): - PYTHON = posixjoin(os.environ.get('TOOLS'), - 'python%s' % PYSHORTVER, - 'python.exe') - findPython = runcmd("which %s" % PYTHON, True, False) - msg('Found %s at %s' % (PYTHON, findPython)) + if isWindows: + if os.environ.get('TOOLS'): + TOOLS = os.environ.get('TOOLS') + if 'cygdrive' in TOOLS: + TOOLS = runcmd('cygpath -w '+TOOLS, True, False) + PYTHON = posixjoin(TOOLS, + 'python%s' % PYSHORTVER, + 'python.exe') + else: + # if TOOLS is not set then default to the python that invoked + # this script + PYTHON = sys.executable + PYVER = sys.version[:3] + PYSHORTVER = PYVER[0] + PYVER[2] + msg('Using %s' % PYTHON) + else: + findPython = runcmd("which %s" % PYTHON, True, False) + msg('Found %s at %s' % (PYTHON, findPython)) msg(runcmd('%s -c "import sys; print sys.version"' % PYTHON, True, False)) def setDevModeOptions(args): - # Using --dev is a shortcut for setting several build options that I use - # while working on the code in my local workspaces. Most people will - # probably not use this so it is not part for the documented options and - # is explicitly handled here before the options parser is created. + # Using --dev is a shortcut for setting several build options that + # I use while working on the code in my local workspaces. Most + # people will probably not use this so it is not part for the + # documented options and is explicitly handled here before the + # options parser is created. If anybody besides Robin is using + # this option do not depend on the options it inserts into the + # args list being consistent. They could change at any update + # from the repository. myDevModeOptions = [ '--sip', - '--debug', '--build_dir=../bld', '--prefix=/opt/wx/2.9', + + # These will be ignored on the other platforms so it is okay to + # include them here '--osx_cocoa', '--mac_arch=i386', ] + if not isWindows: + myDevModeOptions.append('--debug') if '--dev' in args: idx = args.index('--dev') # replace the --dev item with the items from the list @@ -173,23 +195,32 @@ def phoenixDir(): def wxDir(): WXWIN = os.environ.get('WXWIN') if not WXWIN: - for rel in ['../wxWidgets', '..']: + for rel in ['../wxWidgets', '../wx', '..']: path = os.path.join(phoenixDir(), rel) - if path and os.path.exists(path): + if path and os.path.exists(path) and os.path.isdir(path): WXWIN = os.path.abspath(os.path.join(phoenixDir(), rel)) break assert WXWIN not in [None, ''] return WXWIN -if sys.platform.startswith("win"): - CPU = os.environ.get('CPU') - if CPU == 'AMD64': - dllDir = os.path.join(wxDir(), "lib", "vc_amd64_dll") - else: - dllDir = os.path.join(wxDir(), "lib", "vc_dll") - buildDir = os.path.join(wxDir(), "build", "msw") +def getMSWSettings(options): + class MSWsettings(object): + pass + msw = MSWsettings() + msw.CPU = os.environ.get('CPU') + if msw.CPU == 'AMD64': + msw.dllDir = posixjoin(wxDir(), "lib", "vc_amd64_dll") + else: + msw.dllDir = posixjoin(wxDir(), "lib", "vc_dll") + msw.buildDir = posixjoin(wxDir(), "build", "msw") + + #msw.build_type_ext = "u" + #if options.debug: + # msw.build_type_ext = "ud" + return msw + @@ -211,6 +242,8 @@ def makeOptionParser(): ("build_dir", ("", "Directory to store wx build files. (Not used on Windows)")), ("extra_setup", ("", "Extra args to pass on setup.py's command line.")), ("extra_make", ("", "Extra args to pass on [n]make's command line.")), + ("both", (False, "Build both a debug and release version. (Only used on Windows)")), + ("unicode", (True, "Build wxPython with unicode support (always on for wx2.9)")), ] parser = optparse.OptionParser("build options:") @@ -245,7 +278,7 @@ def getBuildDir(options): BUILD_DIR = opj(phoenixDir(), 'bld') if options.build_dir: BUILD_DIR = os.path.abspath(options.build_dir) - if sys.platform == 'darwin': + if isDarwin: port = 'cocoa' if options.osx_carbon: port = 'carbon' @@ -275,17 +308,27 @@ def macFixDependencyInstallName(destdir, prefix, extension, buildDir): #--------------------------------------------------------------------------- +def _doDox(arg): + if isWindows: + d = posixjoin(wxDir(), 'docs/doxygen') + d = d.replace('\\', '/') + cmd = 'c:/cygwin/bin/bash.exe -l -c "cd %s && ./regen.sh %s"' % (d, arg) + else: + pwd = pushDir(posixjoin(wxDir(), 'docs/doxygen')) + cmd = './regen.sh %s' % arg + runcmd(cmd) + + def dox(options, args): msg('Running command: dox') - pwd = pushDir(posixjoin(wxDir(), 'docs/doxygen')) - runcmd('./regen.sh xml') - + _doDox('xml') + def doxhtml(options, args): msg('Running command: doxhtml') - pwd = pushDir(posixjoin(wxDir(), 'docs/doxygen')) - runcmd('./regen.sh html chm') - + _doDox('html chm') + + def etg(options, args): msg('Running command: etg') @@ -306,6 +349,20 @@ def etg(options, args): if newer_group(deps, sipfile): runcmd('%s %s --sip' % (PYTHON, script)) + +def sip(options, args): + msg('Running command: sip') + cfg = Config() + for src_name in glob.glob(opj(cfg.SIPGEN, '_*.sip')): + src_name = src_name.replace('\\', '/') + base = os.path.basename(os.path.splitext(src_name)[0]) + sbf = posixjoin(cfg.SIPOUT, base) + '.sbf' + pycode = posixjoin(cfg.PKGDIR, base) + '.py' + pycode = '-X pycode:'+pycode + cmd = '%s %s -c %s -b %s %s %s' % \ + (cfg.SIP, cfg.SIPOPTS, cfg.SIPOUT, sbf, pycode, src_name) + runcmd(cmd) + def touch(options, args): msg('Running command: touch') @@ -330,19 +387,20 @@ def build(options, args): def build_wx(options, args): msg('Running command: build_wx') - build_options = list() + build_options = ['--wxpython', '--unicode'] - if sys.platform.startswith('win'): - # TODO: Add Windows specific build stuff here + if isWindows: + # Windows-specific pre build stuff pass - else: + else: + # Platform is something other than MSW if options.osx_carbon: options.osx_cocoa = False BUILD_DIR = getBuildDir(options) DESTDIR = options.installdir PREFIX = options.prefix - if options.mac_framework and sys.platform.startswith("darwin"): + if options.mac_framework and isDarwin: # TODO: Don't hard-code this path PREFIX = "/Library/Frameworks/wx.framework/Versions/%s" % version2 build_options.append('--prefix=%s' % PREFIX) @@ -369,14 +427,14 @@ def build_wx(options, args): else: build_options.append("--no_config") - if sys.platform.startswith("darwin") and options.osx_cocoa: + if isDarwin and options.osx_cocoa: build_options.append("--osx_cocoa") if options.install: build_options.append('--installdir=%s' % DESTDIR) build_options.append("--install") - if options.mac_framework and sys.platform.startswith("darwin"): + if options.mac_framework and isDarwin: build_options.append("--mac_framework") # Change to what will be the wxWidgets build folder @@ -384,7 +442,7 @@ def build_wx(options, args): # because they may be specified as relative paths.) pwd = pushDir(BUILD_DIR) - if options.debug: + if options.debug or (isWindows and options.both): build_options.append('--debug') if options.extra_make: @@ -395,8 +453,16 @@ def build_wx(options, args): wxscript = os.path.join(wxDir(), "build/tools/build-wxwidgets.py") sys.path.insert(0, os.path.dirname(wxscript)) wxbuild = __import__('build-wxwidgets') + print 'wxWidgets build options:', build_options wxbuild.main(wxscript, build_options) + + # build again without the --debug flag? + if isWindows and options.both: + build_options.remove('--debug') + print 'wxWidgets build options:', build_options + wxbuild.main(wxscript, build_options) + except: print "ERROR: failed building wxWidgets" import traceback @@ -408,27 +474,16 @@ def build_wx(options, args): def build_py(options, args): msg('Running command: build_py') - if False: - # For now, just run setup.py. - # This will need more work later, either to call build-wxpython - # or to implement its important parts here - pwd = pushDir(phoenixDir()) - runcmd(PYTHON + ' setup.py build_ext ' - '--inplace ' - '--debug ' - 'USE_SIP=1 ' - 'WXPORT=osx_cocoa ' - 'ARCH=i386 ' - 'WX_CONFIG=/projects/wx/2.9/bld/osx_cocoa/wx-config' - + extraArgs) - return - - if sys.platform.startswith("win"): + if isWindows: # Copy the wxWidgets DLLs to the wxPython pacakge folder - dlls = glob.glob(os.path.join(dllDir, "wx*" + version2_nodot + dll_type + "*.dll")) + \ - glob.glob(os.path.join(dllDir, "wx*" + version3_nodot + dll_type + "*.dll")) + msw = getMSWSettings(options) + cfg = Config() + + # NOTE: this will copy both debug and release DLLs if they both exist... + ver = version3_nodot if unstable_series else version2_nodot + dlls = glob.glob(os.path.join(msw.dllDir, "wx*%s*.dll" % ver)) for dll in dlls: - shutil.copyfile(dll, os.path.join(phoenixDir(), "wxPhoenix", os.path.basename(dll))) + shutil.copyfile(dll, posixjoin(phoenixDir(), cfg.PKGDIR, os.path.basename(dll))) BUILD_DIR = getBuildDir(options) DESTDIR = options.installdir @@ -436,20 +491,20 @@ def build_py(options, args): build_options = list() - if options.debug: + if options.debug or (isWindows and options.both): build_options.append("--debug") if options.sip: build_options.append('USE_SIP=1') - if options.mac_arch: + if isDarwin and options.mac_arch: build_options.append("ARCH=%s" % options.mac_arch) - if sys.platform.startswith("darwin") and options.osx_cocoa: + if isDarwin and options.osx_cocoa: build_options.append("WXPORT=osx_cocoa") - if sys.platform.startswith("darwin") and options.osx_carbon: + if isDarwin and options.osx_carbon: build_options.append("WXPORT=osx_carbon") build_base = 'build' - if sys.platform.startswith("darwin"): + if isDarwin: if options.osx_cocoa: build_base += '/cocoa' else: @@ -460,14 +515,9 @@ def build_py(options, args): if options.install: build_mode = "build" - if not sys.platform.startswith("win"): + if not isWindows: if options.install: wxlocation = DESTDIR + PREFIX - #print '-='*20 - #print 'DESTDIR:', DESTDIR - #print 'PREFIX:', PREFIX - #print 'wxlocation:', wxlocation - #print '-='*20 build_options.append('WX_CONFIG="%s/bin/wx-config --prefix=%s"' % (wxlocation, wxlocation)) else: @@ -479,7 +529,13 @@ def build_py(options, args): command = PYTHON + " -u ./setup.py %s %s %s" % \ (build_mode, " ".join(build_options), options.extra_setup) runcmd(command) - + + if isWindows and options.both: + build_options.remove('--debug') + command = PYTHON + " -u ./setup.py %s %s %s" % \ + (build_mode, " ".join(build_options), options.extra_setup) + runcmd(command) + # Do an install? if options.install: # only add the --prefix flag if we have an explicit request to do @@ -495,7 +551,7 @@ def build_py(options, args): (WXPY_PREFIX, " ".join(build_options), options.extra_setup) runcmd(command) - if sys.platform.startswith("darwin") and DESTDIR: + if isDarwin and DESTDIR: # Now that we are finished with the build fix the ids and # names in the wx .dylibs wxbuild.macFixupInstallNames(DESTDIR, PREFIX, BUILD_DIR) @@ -513,12 +569,29 @@ def build_py(options, args): print "------------ BUILD FINISHED ------------" print "To run the wxPython demo:" print " - Set your PYTHONPATH variable to %s." % phoenixDir() - if not sys.platform.startswith("win") and not options.install: + if not isWindows and not options.install: print " - Set your (DY)LD_LIBRARY_PATH to %s" % BUILD_DIR + "/lib" print " - Run python demo/demo.py" print + +def clean_wx(options, args): + msg('Running command: clean_wx') + + +def clean_py(options, args): + msg('Running command: clean_py') + + +def cleanall(options, args): + msg('Running command: cleanall') + + clean_wx(options, args) + clean_py(options, args) + + + #--------------------------------------------------------------------------- if __name__ == '__main__': diff --git a/etg/_core.py b/etg/_core.py index b1a89a45..aa6c774e 100644 --- a/etg/_core.py +++ b/etg/_core.py @@ -61,6 +61,7 @@ INCLUDES = [ 'defs', 'validate', 'window', 'toplevel', + 'frame', ] diff --git a/etg/app.py b/etg/app.py index 2c0ad2ba..9a5bf2f8 100644 --- a/etg/app.py +++ b/etg/app.py @@ -49,7 +49,24 @@ def run(): c.find('OnInitCmdLine').ignore() c.find('HandleEvent').ignore() + c.find('UsesEventLoop').ignore() + + # We will use OnAssertFailure, but I don't think we should let it be + # overridden in Python. + c.find('OnAssertFailure').ignore() + + # TODO: Decide if these should be visible from Python. They are for + # dealing with C/C++ exceptions, but perhaps we could also add the ability + # to deal with unhandled Python exceptions using these (overridable) + # methods too. + c.find('OnExceptionInMainLoop').ignore() + c.find('OnFatalException').ignore() + c.find('OnUnhandledException').ignore() + + c.find('ExitMainLoop').isVirtual = False + + c.addProperty('AppDisplayName GetAppDisplayName SetAppDisplayName') c.addProperty('AppName GetAppName SetAppName') c.addProperty('ClassName GetClassName SetClassName') @@ -57,21 +74,57 @@ def run(): 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.insertCppCode('src/app_ex.cpp') + c.includeCppCode('src/app_ex.cpp') - for item in c.allItems(): # change the class name, ctors and dtor names + # Now change the class name, ctors and dtor names from wxApp to wxPyApp + for item in c.allItems(): if item.name == 'wxApp': - item.name = 'wxPyApp' + item.name = 'wxPyApp' if item.name == '~wxApp': item.name = '~wxPyApp' c.find('ProcessMessage').ignore() + + 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__ + self->MacHideApp(); + #endif + """) + + # Remove the virtualness from these methods + for m in [ 'GetDisplayMode', 'GetLayoutDirection', 'GetTopWindow', 'IsActive', + 'SafeYield', 'SafeYieldFor', 'SendIdleEvents', 'SetDisplayMode', + 'SetNativeTheme', ]: + c.find(m).isVirtual = False + + # Methods we implement in wxPyApp beyond what are in wxApp, plus some + # overridden virtuals (or at least some that we want the wrapper generator + # to treat as if they are overridden.) + c.addItem(etgtools.WigCode("""\ + wxAppAssertMode GetAssertMode(); + void SetAssertMode(wxAppAssertMode mode); + void _BootstrapApp(); + static bool IsDisplayAvailable(); + + virtual int MainLoop(); + virtual void OnPreInit(); + virtual bool OnInit(); + virtual bool OnInitGui(); + virtual int OnRun(); + virtual int OnExit(); + """)) + + c.addProperty('DisplayMode GetDisplayMode SetDisplayMode') c.addProperty('ExitOnFrameDelete GetExitOnFrameDelete SetExitOnFrameDelete') c.addProperty('LayoutDirection GetLayoutDirection') @@ -79,26 +132,9 @@ def run(): 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__ - self->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{ + enum wxAppAssertMode { wxPYAPP_ASSERT_SUPPRESS = 1, wxPYAPP_ASSERT_EXCEPTION = 2, wxPYAPP_ASSERT_DIALOG = 4, @@ -131,7 +167,7 @@ def run(): if item.name == 'wxEntry': item.ignore() - + #----------------------------------------------------------------- tools.doCommonTweaks(module) diff --git a/etg/colour.py b/etg/colour.py index 63a634e2..2b52e2fd 100644 --- a/etg/colour.py +++ b/etg/colour.py @@ -42,7 +42,7 @@ def run(): return new wxColour(wxMacCreateCGColorFromHITheme(themeBrushID)); #else wxPyRaiseNotImplemented(); - sipIsErr = 1; + _isErr = 1; return NULL; #endif """, factory=True) diff --git a/etg/defs.py b/etg/defs.py index 7023f3dc..c1fc20dc 100644 --- a/etg/defs.py +++ b/etg/defs.py @@ -46,7 +46,7 @@ def run(): module.find('wxSwap').ignore() module.find('wxVaCopy').ignore() - # add some typedefs for wxChar, wxUChar + # add some typedefs for wxChar, wxUChar, etc. td = module.find('wxUIntPtr') module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxUChar')) module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxChar')) @@ -69,6 +69,9 @@ def run(): class wxCaret; class wxIcon; class wxIconBundle; + class wxStatusBar; + class wxToolBar; + class wxMenuBar; """)) diff --git a/etg/event.py b/etg/event.py index cda76707..180538b6 100644 --- a/etg/event.py +++ b/etg/event.py @@ -63,6 +63,11 @@ ITEMS = [ #'wxThreadEvent', ] + +OTHERDEPS = [ 'src/event_ex.py', + 'src/event_ex.cpp', + ] + #--------------------------------------------------------------------------- def run(): @@ -81,22 +86,86 @@ def run(): """) - # 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() + c.addPublic() # 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() + c.includeCppCode('src/event_ex.cpp') + module.includePyCode('src/event_ex.py') + + # Connect and disconnect methods for wxPython. Hold a reference to the + # event handler function in the event table, so we can fetch it later when + # it is time to handle the event. + c.addCppMethod( + 'void', 'Connect', '(int id, int lastId, wxEventType eventType, PyObject* func)', + """\ + if (PyCallable_Check(func)) { + self->Connect(id, lastId, eventType, + (wxObjectEventFunction)(wxEventFunction) + &wxPyCallback::EventThunker, + new wxPyCallback(func)); + } + else if (func == Py_None) { + self->Disconnect(id, lastId, eventType, + (wxObjectEventFunction)(wxEventFunction) + &wxPyCallback::EventThunker); + } + else { + _isErr = 1; + PyErr_SetString(PyExc_TypeError, "Expected callable object or None."); + } + """) + + c.addCppMethod( + 'bool', 'Disconnect', '(int id, int lastId=-1, ' + 'wxEventType eventType=wxEVT_NULL, ' + 'PyObject* func=NULL)', + """\ + if (func && func != Py_None) { + // Find the current matching binder that has this function + // pointer and dissconnect that one. Unfortuneatly since we + // wrapped the PyObject function pointer in another object we + // have to do the searching ourselves... + wxList::compatibility_iterator node = self->GetDynamicEventTable()->GetFirst(); + while (node) + { + wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData(); + if ((entry->m_id == id) && + ((entry->m_lastId == lastId) || (lastId == wxID_ANY)) && + ((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) && + // FIXME? + //((entry->m_fn->IsMatching((wxObjectEventFunction)(wxEventFunction)&wxPyCallback::EventThunker))) && + (entry->m_callbackUserData != NULL)) + { + wxPyCallback *cb = (wxPyCallback*)entry->m_callbackUserData; + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + int result = PyObject_Compare(cb->m_func, func); + wxPyEndBlockThreads(blocked); + if (result == 0) { + delete cb; + self->GetDynamicEventTable()->Erase(node); + delete entry; + return true; + } + } + node = node->GetNext(); + } + return false; + } + else { + return self->Disconnect(id, lastId, eventType, + (wxObjectEventFunction) + &wxPyCallback::EventThunker); + } + """) + # wxEventTable is not documented so we have to ignore SearchEventTable. # TODO: Should wxEventTable be available to language bindings? @@ -109,7 +178,12 @@ def run(): c.find('GetClientData').ignore() c.find('SetClientData').ignore() + # The only virtual we care about overriding is ProcessEvent, ignore the rest + tools.removeVirtuals(c) + c.find('ProcessEvent').isVirtual = True + + #--------------------------------------- # wxEvent c = module.find('wxEvent') diff --git a/etg/frame.py b/etg/frame.py new file mode 100644 index 00000000..f0caf51f --- /dev/null +++ b/etg/frame.py @@ -0,0 +1,65 @@ +#--------------------------------------------------------------------------- +# Name: etg/frame.py +# Author: Robin Dunn +# +# Created: 6-Dec-2010 +# Copyright: (c) 2010 by Total Control Software +# License: wxWindows License +#--------------------------------------------------------------------------- + +import etgtools +import etgtools.tweaker_tools as tools + +PACKAGE = "wx" +MODULE = "_core" +NAME = "frame" # 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 = [ 'wxFrame' ] + +#--------------------------------------------------------------------------- + +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('wxFrame') + assert isinstance(c, etgtools.ClassDef) + tools.fixWindowClass(c) + + c.find('wxFrame.title').default = 'wxEmptyString' + c.find('Create.title').default = 'wxEmptyString' + + c.find('SetStatusWidths.n').arraySize = True + c.find('SetStatusWidths.widths_field').array = True + + c.addProperty('MenuBar GetMenuBar SetMenuBar') + c.addProperty('StatusBar GetStatusBar SetStatusBar') + c.addProperty('StatusBarPane GetStatusBarPane SetStatusBarPane') + c.addProperty('ToolBar GetToolBar SetToolBar') + + + tools.removeVirtuals(c) + tools.addWindowVirtuals(c) + + # TODO: should these go into a tools.addFrameVirtuals function? + c.find('OnCreateStatusBar').isVirtual = True + c.find('OnCreateToolBar').isVirtual = True + + + #----------------------------------------------------------------- + tools.doCommonTweaks(module) + tools.runGenerators(module) + + +#--------------------------------------------------------------------------- +if __name__ == '__main__': + run() + diff --git a/etg/object.py b/etg/object.py index a2e8d3ca..0fe8cae8 100644 --- a/etg/object.py +++ b/etg/object.py @@ -35,21 +35,27 @@ def run(): # 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') + #-------------------------------------------------- + c = module.find('wxRefCounter') assert isinstance(c, etgtools.ClassDef) + c.find('~wxRefCounter').ignore(False) + c.addPrivateCopyCtor() + + + + #-------------------------------------------------- + c = module.find('wxObject') + c.find('operator delete').ignore() + c.find('operator new').ignore() + c.find('GetClassInfo').ignore() + c.find('IsKindOf').ignore() c.addCppMethod('const wxChar*', 'GetClassName', '()', body='return self->GetClassInfo()->GetClassName();', diff --git a/etg/tooltip.py b/etg/tooltip.py index 571ccf02..12e4c7c5 100644 --- a/etg/tooltip.py +++ b/etg/tooltip.py @@ -40,6 +40,8 @@ def run(): c.addProperty('Tip GetTip SetTip') c.addProperty('Window GetWindow') + c.addPrivateCopyCtor() + #----------------------------------------------------------------- tools.doCommonTweaks(module) diff --git a/etg/toplevel.py b/etg/toplevel.py index 2aadfe71..bc17f7f9 100644 --- a/etg/toplevel.py +++ b/etg/toplevel.py @@ -74,6 +74,10 @@ def run(): c.addProperty('TmpDefaultItem GetTmpDefaultItem SetTmpDefaultItem') c.addProperty('OSXModified OSXIsModified OSXSetModified') + + tools.removeVirtuals(c) + tools.addWindowVirtuals(c) + #----------------------------------------------------------------- tools.doCommonTweaks(module) tools.runGenerators(module) diff --git a/etg/window.py b/etg/window.py index 55d4f3bc..b86feece 100644 --- a/etg/window.py +++ b/etg/window.py @@ -36,8 +36,31 @@ def run(): c = module.find('wxWindow') assert isinstance(c, etgtools.ClassDef) + + # First we need to let the wrapper generator know about wxWindowBase since + # AddChild and RemoveChild need to use that type in order to be virtualized. + wc = etgtools.WigCode("""\ + class wxWindowBase : wxEvtHandler /Abstract/ + { + public: + virtual void AddChild( wxWindowBase* child ); + virtual void RemoveChild( wxWindowBase* child ); + }; + """) + module.insertItemBefore(c, wc) - c.insertCppCode('src/window_ex.cpp') + # Now change the base class of wxWindow + c.bases = ['wxWindowBase'] + + # And fix the arg types we get from Doxy + c.find('AddChild.child').type = 'wxWindowBase*' + c.find('RemoveChild.child').type = 'wxWindowBase*' + + + # We now return you to our regularly scheduled programming... + tools.fixWindowClass(c) + + c.includeCppCode('src/window_ex.cpp') # ignore some overloads that will be ambiguous afer wrapping c.find('GetChildren').overloads = [] @@ -85,7 +108,8 @@ def run(): #endif """) - # Make these be available on Windows, and empty stubs otherwise + # Make the Register/UnregisterHotKey functions be available on Windows, + # and empty stubs otherwise c.find('RegisterHotKey').setCppCode("""\ #ifdef __WXMSW__ sipRes = sipCpp->RegisterHotKey(hotkeyId, modifiers, virtualKeyCode); @@ -103,6 +127,7 @@ def run(): c.find('RegisterHotKey').isVirtual = False c.find('UnregisterHotKey').isVirtual = False + c.find('SetDoubleBuffered').setCppCode("""\ #if defined(__WXGTK20__) || defined(__WXMSW__) sipCpp->SetDoubleBuffered(on); @@ -117,16 +142,12 @@ def run(): # MSW only. Do we want them wrapped? c.find('GetAccessible').ignore() c.find('SetAccessible').ignore() - - + # Make some of the protected methods visible and overridable from Python - c.find('DoCentre').ignore(False) - c.find('DoGetBestSize').ignore(False) - c.find('SetInitialBestSize').ignore(False) c.find('SendDestroyEvent').ignore(False) - c.find('ProcessEvent').ignore(False) - - c.addPyMethod('PostCreate', '()', 'pass') + + c.find('Destroy').transferThis=True + c.addPyMethod('PostCreate', '(self, pre)', 'pass') # transfer ownership of these parameters to the C++ object c.find('SetCaret.caret').transfer = True @@ -191,20 +212,39 @@ def run(): c.addProperty('WindowStyle GetWindowStyle SetWindowStyle') c.addProperty('WindowStyleFlag GetWindowStyleFlag SetWindowStyleFlag') c.addProperty('WindowVariant GetWindowVariant SetWindowVariant') - c.addProperty('Shown IsShown Show') c.addProperty('Enabled IsEnabled Enable') c.addProperty('TopLevel IsTopLevel') - - ##c.addProperty('GtkWidget GetGtkWidget') - c.addProperty('MinClientSize GetMinClientSize SetMinClientSize') c.addProperty('MaxClientSize GetMaxClientSize SetMaxClientSize') + ##c.addProperty('GtkWidget GetGtkWidget') + + + + # We probably won't ever need most of the wxWindow virtuals to be + # overridable in Python, so we'll clear all the virtual flags here and add + # back those that we want to keep in the next step. + tools.removeVirtuals(c) + tools.addWindowVirtuals(c) + + + + module.addPyCode('''\ + class FrozenWindow(object): + """ + A context manager to be used with Python 'with' statements + that will freeze the given window for the duration of the + with block. + """ + def __init__(self, window): + self._win = window + def __enter__(self): + self._win.Freeze() + return self + def __exit__(self, exc_type, exc_val, exc_tb): + self._win.Thaw() + ''') - - tools.fixWindowClass(c) - - #----------------------------------------------------------------- tools.doCommonTweaks(module) tools.runGenerators(module) diff --git a/etgtools/extractors.py b/etgtools/extractors.py index 56bed619..9fd8473c 100644 --- a/etgtools/extractors.py +++ b/etgtools/extractors.py @@ -86,6 +86,17 @@ class BaseDef(object): else: # got though all items with no match raise ExtractorError("Unable to find item named '%s' within %s named '%s'" % (head, self.__class__.__name__, self.name)) + + def findItem(self, name): + """ + Just like find() but does not raise an exception if the item is not found. + """ + try: + item = self.find(name) + return item + except ExtractorError: + return None + def addItem(self, item): self.items.append(item) @@ -228,9 +239,11 @@ class FunctionDef(BaseDef): if element is not None: self.extract(element) + def releaseGIL(self, release=True): self.pyReleaseGIL = release - + + def extract(self, element): super(FunctionDef, self).extract(element) self.type = flattenNode(element.find('type')) @@ -422,7 +435,7 @@ class ClassDef(BaseDef): self.cppCode.append(code) - def insertCppCode(self, filename): + def includeCppCode(self, filename): self.addCppCode(file(filename).read()) diff --git a/etgtools/sip_generator.py b/etgtools/sip_generator.py index a698dba5..cb273f6d 100644 --- a/etgtools/sip_generator.py +++ b/etgtools/sip_generator.py @@ -360,7 +360,7 @@ from %s import * stream.write(')') if prop.briefDoc: stream.write(' // %s' % prop.briefDoc) - stream.write('\n\n') + stream.write('\n') def generateMethod(self, method, stream, indent): diff --git a/etgtools/tweaker_tools.py b/etgtools/tweaker_tools.py index bd6bcc61..4f36bb2a 100644 --- a/etgtools/tweaker_tools.py +++ b/etgtools/tweaker_tools.py @@ -91,10 +91,6 @@ def fixWindowClass(klass): # give the id param a default value klass.find('%s.id' % klass.name).default = 'wxID_ANY' klass.find('Create.id').default = 'wxID_ANY' - # look for wxByte parameters - #for item in klass.allItems(): - # if hasattr(item, 'type') and item.type == 'wxByte': - # item.pyInt = True def removeVirtuals(klass): @@ -108,6 +104,80 @@ def removeVirtuals(klass): if isinstance(item, extractors.MethodDef): item.isVirtual = item.isPureVirtual = False + +def addWindowVirtuals(klass): + """ + + """ + publicWindowVirtuals = [ + ('GetClientAreaOrigin', 'wxPoint GetClientAreaOrigin() const'), + ('Validate', 'bool Validate()'), + ('TransferDataToWindow', 'bool TransferDataToWindow()'), + ('TransferDataFromWindow', 'bool TransferDataFromWindow()'), + ('InitDialog', 'void InitDialog()'), + ('AcceptsFocus', 'bool AcceptsFocus() const'), + ('AcceptsFocusRecursively', 'bool AcceptsFocusRecursively() const'), + ('AcceptsFocusFromKeyboard', 'bool AcceptsFocusFromKeyboard() const'), + ('AddChild', 'void AddChild( wxWindowBase *child )'), + ('RemoveChild', 'void RemoveChild( wxWindowBase *child )'), + ('InheritAttributes', 'void InheritAttributes()'), + ('ShouldInheritColours', 'bool ShouldInheritColours() const'), + ('HasTransparentBackground', 'bool HasTransparentBackground()'), + ('OnInternalIdle', 'void OnInternalIdle()'), + ('GetMainWindowOfCompositeControl', + 'wxWindow *GetMainWindowOfCompositeControl()'), + #('Enable', ''), We have DoEnable now... + + ## What about these? + #bool HasMultiplePages() const + #void UpdateWindowUI(long flags = wxUPDATE_UI_NONE); + #void DoUpdateWindowUI(wxUpdateUIEvent& event) ; + ] + + protectedWindowVirtuals = [ + ('ProcessEvent', 'bool ProcessEvent(wxEvent & event)'), + ('DoEnable', 'void DoEnable(bool enable)'), + ('OnEnabled', 'void OnEnabled(bool enabled)'), + ('DoGetPosition', 'void DoGetPosition(int *x, int *y) const'), + ('DoGetSize', 'void DoGetSize(int *width, int *height) const'), + ('DoGetClientSize', 'void DoGetClientSize(int *width, int *height) const'), + ('DoGetBestSize', 'wxSize DoGetBestSize() const'), + ('DoGetBestClientSize', 'wxSize DoGetBestClientSize() const'), + ('DoSetSize', 'void DoSetSize(int x, int y, int width, int height, int sizeFlags)'), + ('DoSetClientSize', 'void DoSetClientSize(int width, int height)'), + ('DoSetSizeHints', 'void DoSetSizeHints( int minW, int minH, int maxW, int maxH, int incW, int incH )'), + ('DoGetBorderSize', 'wxSize DoGetBorderSize() const'), + ('DoMoveWindow', 'void DoMoveWindow(int x, int y, int width, int height)'), + ('DoSetWindowVariant', 'void DoSetWindowVariant( wxWindowVariant variant)'), + ('GetDefaultBorder', 'wxBorder GetDefaultBorder() const'), + ('GetDefaultBorderForControl', + 'wxBorder GetDefaultBorderForControl() const'), + + ## What about these? + #('DoGetScreenPosition', 'void DoGetScreenPosition(int *x, int *y) const'), + #('DoSetVirtualSize', 'void DoSetVirtualSize( int x, int y )'), + #('DoGetVirtualSize', 'wxSize DoGetVirtualSize() const'), + ] + + def _processItems(klass, prot, virtuals): + txt = '' + for name, decl in virtuals: + m = klass.findItem(name) + if m: + m.ignore(False) + m.isVirtual = True + else: + txt += 'virtual %s;\n' % decl + if txt: + txt = prot + txt + return txt + + txt = _processItems(klass, 'public:\n', publicWindowVirtuals) + klass.addItem(extractors.WigCode(txt)) + txt = _processItems(klass, 'protected:\n', protectedWindowVirtuals) + klass.addItem(extractors.WigCode(txt)) + + def getEtgFiles(names): """ diff --git a/samples/simple/deprecated.py b/samples/simple/deprecated.py new file mode 100644 index 00000000..48e2053c --- /dev/null +++ b/samples/simple/deprecated.py @@ -0,0 +1,6 @@ +import wxPhoenix as wx +app = wx.PySimpleApp() # Should see a deprecation warning here +frm = wx.Frame(None) +frm.Show() +app.MainLoop() + diff --git a/samples/simple/events.py b/samples/simple/events.py new file mode 100644 index 00000000..905c66f4 --- /dev/null +++ b/samples/simple/events.py @@ -0,0 +1,16 @@ + +import wxPhoenix as wx + +class MyFrame(wx.Frame): + def __init__(self, *args, **kw): + wx.Frame.__init__(self, *args, **kw) + self.Bind(wx.EVT_SIZE, self.onSize) + + def onSize(self, evt): + print repr(evt.Size) + +app = wx.App() +frm = MyFrame(None, title="Hello Events", size=(480,360)) +frm.Show() +app.MainLoop() + diff --git a/samples/simple/hello.py b/samples/simple/hello.py new file mode 100644 index 00000000..f7b30627 --- /dev/null +++ b/samples/simple/hello.py @@ -0,0 +1,11 @@ +import sys, os +import wxPhoenix as wx + +#print 'PID:', os.getpid(); raw_input('Ready to start, press enter...') + +app = wx.App() +frm = wx.Frame(None, title="Hello World!") +frm.Show() +app.MainLoop() + + diff --git a/sip/gen/_core.sip b/sip/gen/_core.sip index 88cdecd8..48dd2040 100644 --- a/sip/gen/_core.sip +++ b/sip/gen/_core.sip @@ -79,6 +79,7 @@ from _core import * %Include validate.sip %Include window.sip %Include toplevel.sip +%Include frame.sip %ModuleCode @@ -164,7 +165,6 @@ void wxPyCoreModuleInject(PyObject* moduleDict) #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # This code block was included from src/core_ex.py - # 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 @@ -207,7 +207,7 @@ def deprecated(func): def new_func(*args, **kwargs): import warnings warnings.warn("Call to deprecated item %s." % func.__name__, - category=DeprecationWarning) + DeprecationWarning, stacklevel=2) return func(*args, **kwargs) new_func.__name__ = func.__name__ new_func.__doc__ = func.__doc__ diff --git a/sip/gen/app.sip b/sip/gen/app.sip index 3232ce9f..b381758e 100644 --- a/sip/gen/app.sip +++ b/sip/gen/app.sip @@ -9,7 +9,7 @@ //--------------------------------------------------------------------------- %ModuleHeaderCode - enum wxAppAssertMode{ + enum wxAppAssertMode { wxPYAPP_ASSERT_SUPPRESS = 1, wxPYAPP_ASSERT_EXCEPTION = 2, wxPYAPP_ASSERT_DIALOG = 4, @@ -38,7 +38,6 @@ public: virtual int MainLoop(); - virtual void ExitMainLoop(); virtual @@ -48,9 +47,6 @@ public: wxEventLoopBase * GetMainLoop(); - virtual - bool UsesEventLoop(); - virtual void ProcessPendingEvents(); @@ -70,15 +66,6 @@ public: wxObject * object ); - virtual - void OnAssertFailure( - const wxChar * file, - int line, - const wxChar * func, - const wxChar * cond, - const wxChar * msg - ); - virtual void OnEventLoopEnter( wxEventLoopBase * loop @@ -89,24 +76,15 @@ public: wxEventLoopBase * loop ); - virtual - bool OnExceptionInMainLoop(); - virtual int OnExit(); - virtual - void OnFatalException(); - virtual bool OnInit(); virtual int OnRun(); - virtual - void OnUnhandledException(); - wxString GetAppDisplayName(); wxString GetAppName(); @@ -151,19 +129,14 @@ public: bool IsMainLoopRunning(); %Property(name=AppDisplayName, get=GetAppDisplayName, set=SetAppDisplayName) - %Property(name=AppName, get=GetAppName, set=SetAppName) - %Property(name=ClassName, get=GetClassName, set=SetClassName) - %Property(name=VendorDisplayName, get=GetVendorDisplayName, set=SetVendorDisplayName) - %Property(name=VendorName, get=GetVendorName, set=SetVendorName) - }; // end of class wxAppConsole - enum wxAppAssertMode{ + enum wxAppAssertMode { wxPYAPP_ASSERT_SUPPRESS = 1, wxPYAPP_ASSERT_EXCEPTION = 2, wxPYAPP_ASSERT_DIALOG = 4, @@ -249,6 +222,7 @@ class wxPyApp : wxAppConsole virtual void OnPreInit() { } void _BootstrapApp(); + virtual int MainLoop(); static bool IsDisplayAvailable(); @@ -273,32 +247,32 @@ class wxPyApp : wxAppConsole 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 + + // Copy the values in Python's sys.argv list to a C array of char* to + // be passed to the wxEntryStart function below. 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; + if (sysargv != NULL) { + argc = PyList_Size(sysargv); argv = new char*[argc+1]; - argv[0] = strdup(PyString_AsString(executable)); int x; - for(x=1; x %End + %TypeCode + + class wxPyCallback : public wxEvtHandler { + DECLARE_ABSTRACT_CLASS(wxPyCallback) + public: + wxPyCallback(PyObject* func); + wxPyCallback(const wxPyCallback& other); + ~wxPyCallback(); + + void EventThunker(wxEvent& event); + + PyObject* m_func; + }; + + + + IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxEvtHandler); + + wxPyCallback::wxPyCallback(PyObject* func) { + m_func = func; + Py_INCREF(m_func); + } + + wxPyCallback::wxPyCallback(const wxPyCallback& other) { + m_func = other.m_func; + Py_INCREF(m_func); + } + + wxPyCallback::~wxPyCallback() { + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + Py_DECREF(m_func); + wxPyEndBlockThreads(blocked); + } + + + // #define wxPy_PRECALLINIT "_preCallInit" + // #define wxPy_POSTCALLCLEANUP "_postCallCleanup" + + // This function is used for all events destined for Python event handlers. + void wxPyCallback::EventThunker(wxEvent& event) { + wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData; + PyObject* func = cb->m_func; + PyObject* result; + PyObject* arg; + PyObject* tuple; + bool checkSkip = false; + + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + wxString className = event.GetClassInfo()->GetClassName(); + + // // If the event is one of these types then pass the original + // // event object instead of the one passed to us. + // if ( className == wxT("wxPyEvent") ) { + // arg = ((wxPyEvent*)&event)->GetSelf(); + // checkSkip = ((wxPyEvent*)&event)->GetCloned(); + // } + // else if ( className == wxT("wxPyCommandEvent") ) { + // arg = ((wxPyCommandEvent*)&event)->GetSelf(); + // checkSkip = ((wxPyCommandEvent*)&event)->GetCloned(); + // } + // else { + arg = wxPyConstructObject((void*)&event, className); + // } + + + if (!arg) { + PyErr_Print(); + } else { + // // "intern" the pre/post method names to speed up the HasAttr + // static PyObject* s_preName = NULL; + // static PyObject* s_postName = NULL; + // if (s_preName == NULL) { + // s_preName = PyString_FromString(wxPy_PRECALLINIT); + // s_postName = PyString_FromString(wxPy_POSTCALLCLEANUP); + // } + + // // Check if the event object needs some preinitialization + // if (PyObject_HasAttr(arg, s_preName)) { + // result = PyObject_CallMethodObjArgs(arg, s_preName, arg, NULL); + // if ( result ) { + // Py_DECREF(result); // result is ignored, but we still need to decref it + // PyErr_Clear(); // Just in case... + // } else { + // PyErr_Print(); + // } + // } + + // Call the event handler, passing the event object + tuple = PyTuple_New(1); + PyTuple_SET_ITEM(tuple, 0, arg); // steals ref to arg + result = PyEval_CallObject(func, tuple); + if ( result ) { + Py_DECREF(result); // result is ignored, but we still need to decref it + PyErr_Clear(); // Just in case... + } else { + PyErr_Print(); + } + + // // Check if the event object needs some post cleanup + // if (PyObject_HasAttr(arg, s_postName)) { + // result = PyObject_CallMethodObjArgs(arg, s_postName, arg, NULL); + // if ( result ) { + // Py_DECREF(result); // result is ignored, but we still need to decref it + // PyErr_Clear(); // Just in case... + // } else { + // PyErr_Print(); + // } + // } + + // if ( checkSkip ) { + // // if the event object was one of our special types and + // // it had been cloned, then we need to extract the Skipped + // // value from the original and set it in the clone. + // result = PyObject_CallMethod(arg, "GetSkipped", ""); + // if ( result ) { + // event.Skip(PyInt_AsLong(result)); + // Py_DECREF(result); + // } else { + // PyErr_Print(); + // } + // } + Py_DECREF(tuple); + } + wxPyEndBlockThreads(blocked); + } + %End public: wxEvtHandler(); - virtual ~wxEvtHandler(); - virtual void QueueEvent( wxEvent * event ); - virtual void AddPendingEvent( const wxEvent & event ); @@ -67,12 +190,10 @@ public: bool enabled ); - virtual void SetNextHandler( wxEvtHandler * handler ); - virtual void SetPreviousHandler( wxEvtHandler * handler ); @@ -85,6 +206,80 @@ public: wxEvtHandler(const wxEvtHandler&); + public: + + + %TypeCode + void _wxEvtHandler_Connect(wxEvtHandler* self, int& _isErr, int id, int lastId, wxEventType eventType, PyObject* func) + { + if (PyCallable_Check(func)) { + self->Connect(id, lastId, eventType, + (wxObjectEventFunction)(wxEventFunction) + &wxPyCallback::EventThunker, + new wxPyCallback(func)); + } + else if (func == Py_None) { + self->Disconnect(id, lastId, eventType, + (wxObjectEventFunction)(wxEventFunction) + &wxPyCallback::EventThunker); + } + else { + _isErr = 1; + PyErr_SetString(PyExc_TypeError, "Expected callable object or None."); + } + } + %End + void Connect(int id, int lastId, wxEventType eventType, SIP_PYOBJECT func); + %MethodCode + _wxEvtHandler_Connect(sipCpp, sipIsErr, id, lastId, eventType, func); + %End + + %TypeCode + bool _wxEvtHandler_Disconnect(wxEvtHandler* self, int& _isErr, int id, int lastId, wxEventType eventType, PyObject* func) + { + if (func && func != Py_None) { + // Find the current matching binder that has this function + // pointer and dissconnect that one. Unfortuneatly since we + // wrapped the PyObject function pointer in another object we + // have to do the searching ourselves... + wxList::compatibility_iterator node = self->GetDynamicEventTable()->GetFirst(); + while (node) + { + wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData(); + if ((entry->m_id == id) && + ((entry->m_lastId == lastId) || (lastId == wxID_ANY)) && + ((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) && + // FIXME? + //((entry->m_fn->IsMatching((wxObjectEventFunction)(wxEventFunction)&wxPyCallback::EventThunker))) && + (entry->m_callbackUserData != NULL)) + { + wxPyCallback *cb = (wxPyCallback*)entry->m_callbackUserData; + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + int result = PyObject_Compare(cb->m_func, func); + wxPyEndBlockThreads(blocked); + if (result == 0) { + delete cb; + self->GetDynamicEventTable()->Erase(node); + delete entry; + return true; + } + } + node = node->GetNext(); + } + return false; + } + else { + return self->Disconnect(id, lastId, eventType, + (wxObjectEventFunction) + &wxPyCallback::EventThunker); + } + } + %End + bool Disconnect(int id, int lastId=-1, wxEventType eventType=wxEVT_NULL, SIP_PYOBJECT func=NULL); + %MethodCode + sipRes = _wxEvtHandler_Disconnect(sipCpp, sipIsErr, id, lastId, eventType, func); + %End + }; // end of class wxEvtHandler @@ -171,15 +366,10 @@ public: int StopPropagation(); %Property(name=EventObject, get=GetEventObject, set=SetEventObject) - %Property(name=EventType, get=GetEventType, set=SetEventType) - %Property(name=Id, get=GetId, set=SetId) - %Property(name=Skipped, get=GetSkipped) - %Property(name=Timestamp, get=GetTimestamp, set=SetTimestamp) - private: wxEvent& operator=(const wxEvent&); @@ -255,15 +445,10 @@ public: %End %Property(name=ClientData, get=GetClientData, set=SetClientData) - %Property(name=ExtraLong, get=GetExtraLong, set=SetExtraLong) - %Property(name=Int, get=GetInt, set=SetInt) - %Property(name=Selection, get=GetSelection) - %Property(name=String, get=GetString, set=SetString) - virtual wxEvent* Clone(); @@ -291,7 +476,6 @@ public: bool GetActive(); %Property(name=Active, get=GetActive) - virtual wxEvent* Clone(); @@ -317,7 +501,6 @@ public: wxWindow * GetWindow(); %Property(name=Window, get=GetWindow) - virtual wxEvent* Clone(); @@ -411,7 +594,6 @@ public: ); %Property(name=Position, get=GetPosition, set=SetPosition) - virtual wxEvent* Clone(); @@ -463,11 +645,8 @@ public: wxPoint GetPosition(); %Property(name=Files, get=GetFiles) - %Property(name=NumberOfFiles, get=GetNumberOfFiles) - %Property(name=Position, get=GetPosition) - virtual wxEvent* Clone(); @@ -494,7 +673,6 @@ public: wxDC * GetDC(); %Property(name=DC, get=GetDC) - virtual wxEvent* Clone(); @@ -525,7 +703,6 @@ public: ); %Property(name=Window, get=GetWindow, set=SetWindow) - virtual wxEvent* Clone(); @@ -747,19 +924,12 @@ public: wxCoord GetY(); %Property(name=X, get=GetX) - %Property(name=Y, get=GetY) - %Property(name=KeyCode, get=GetKeyCode) - %Property(name=Position, get=GetPosition) - %Property(name=RawKeyCode, get=GetRawKeyCode) - %Property(name=RawKeyFlags, get=GetRawKeyFlags) - %Property(name=UnicodeKey, get=GetUnicodeKey) - virtual wxEvent* Clone(); @@ -813,9 +983,7 @@ public: bool IsPopup(); %Property(name=Menu, get=GetMenu) - %Property(name=MenuId, get=GetMenuId) - virtual wxEvent* Clone(); @@ -842,7 +1010,6 @@ public: wxWindow * GetCapturedWindow(); %Property(name=CapturedWindow, get=GetCapturedWindow) - virtual wxEvent* Clone(); @@ -964,13 +1131,9 @@ public: bool RightUp(); %Property(name=LinesPerAction, get=GetLinesPerAction) - %Property(name=LogicalPosition, get=GetLogicalPosition) - %Property(name=WheelDelta, get=GetWheelDelta) - %Property(name=WheelRotation, get=GetWheelRotation) - virtual wxEvent* Clone(); @@ -1007,9 +1170,7 @@ public: ); %Property(name=Rect, get=GetRect, set=SetRect) - %Property(name=Position, get=GetPosition, set=SetPosition) - virtual wxEvent* Clone(); @@ -1071,9 +1232,7 @@ public: ); %Property(name=CurrentFocus, get=GetCurrentFocus, set=SetCurrentFocus) - %Property(name=Direction, get=GetDirection, set=SetDirection) - virtual wxEvent* Clone(); @@ -1154,7 +1313,6 @@ public: wxWindow * GetChangedWindow(); %Property(name=ChangedWindow, get=GetChangedWindow, set=SetChangedWindow) - virtual wxEvent* Clone(); @@ -1184,7 +1342,6 @@ public: bool GetPaletteRealized(); %Property(name=PaletteRealized, get=GetPaletteRealized, set=SetPaletteRealized) - virtual wxEvent* Clone(); @@ -1223,9 +1380,7 @@ public: ); %Property(name=Orientation, get=GetOrientation, set=SetOrientation) - %Property(name=Position, get=GetPosition, set=SetPosition) - virtual wxEvent* Clone(); @@ -1263,9 +1418,7 @@ public: ); %Property(name=Orientation, get=GetOrientation, set=SetOrientation) - %Property(name=Position, get=GetPosition, set=SetPosition) - virtual wxEvent* Clone(); @@ -1302,11 +1455,8 @@ public: ); %Property(name=Cursor, get=GetCursor, set=SetCursor) - %Property(name=X, get=GetX) - %Property(name=Y, get=GetY) - virtual wxEvent* Clone(); @@ -1337,7 +1487,6 @@ public: bool IsShown(); %Property(name=Show, get=IsShown, set=SetShow) - virtual wxEvent* Clone(); @@ -1374,9 +1523,7 @@ public: ); %Property(name=Rect, get=GetRect, set=SetRect) - %Property(name=Size, get=GetSize, set=SetSize) - virtual wxEvent* Clone(); @@ -1476,13 +1623,9 @@ public: ); %Property(name=Checked, get=GetChecked, set=Check) - %Property(name=Enabled, get=GetEnabled, set=Enable) - %Property(name=Shown, get=GetShown, set=Show) - %Property(name=Text, get=GetText, set=SetText) - virtual wxEvent* Clone(); @@ -1508,7 +1651,6 @@ public: wxWindow * GetWindow(); %Property(name=Window, get=GetWindow) - virtual wxEvent* Clone(); @@ -1534,7 +1676,6 @@ public: wxWindow * GetWindow(); %Property(name=Window, get=GetWindow) - virtual wxEvent* Clone(); @@ -1841,6 +1982,300 @@ void wxQueueEvent( wxEvent * event ); +%Extract(id=pycode) +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# This code block was included from src/event_ex.py + +class PyEventBinder(object): + """ + Instances of this class are used to bind specific events to event + handlers. + """ + def __init__(self, evtType, expectedIDs=0): + if expectedIDs not in [0, 1, 2]: + raise ValueError, "Invalid number of expectedIDs" + self.expectedIDs = expectedIDs + + if isinstance(evtType, (list, tuple)): + self.evtType = list(evtType) + else: + self.evtType = [evtType] + + + def Bind(self, target, id1, id2, function): + """Bind this set of event types to target using its COnnect() method.""" + for et in self.evtType: + target.Connect(id1, id2, et, function) + + + def Unbind(self, target, id1, id2, handler=None): + """Remove an event binding.""" + success = 0 + for et in self.evtType: + success += target.Disconnect(id1, id2, et, handler) + return success != 0 + + + def _getEvtType(self): + """ + Make it easy to get to the default wxEventType typeID for this + event binder. + """ + return self.evtType[0] + typeId = property(_getEvtType) + + + +def _EvtHandler_Bind(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY): + """ + Bind an event to an event handler. + + :param event: One of the EVT_* objects that specifies the + type of event to bind, + + :param handler: A callable object to be invoked when the + event is delivered to self. Pass None to + disconnect an event handler. + + :param source: Sometimes the event originates from a + different window than self, but you still + want to catch it in self. (For example, a + button event delivered to a frame.) By + passing the source of the event, the event + handling system is able to differentiate + between the same event type from different + controls. + + :param id: Used to spcify the event source by ID instead + of instance. + + :param id2: Used when it is desirable to bind a handler + to a range of IDs, such as with EVT_MENU_RANGE. + """ + if source is not None: + id = source.GetId() + event.Bind(self, id, id2, handler) + + +def _EvtHandler_Unbind(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY, handler=None): + """ + Disconnects the event handler binding for event from self. + Returns True if successful. + """ + if source is not None: + id = source.GetId() + return event.Unbind(self, id, id2, handler) + + +EvtHandler.Bind = _EvtHandler_Bind +EvtHandler.Unbind = _EvtHandler_Unbind +del _EvtHandler_Bind, _EvtHandler_Unbind + + +# Create some event binders +EVT_SIZE = wx.PyEventBinder( wxEVT_SIZE ) +EVT_SIZING = wx.PyEventBinder( wxEVT_SIZING ) +EVT_MOVE = wx.PyEventBinder( wxEVT_MOVE ) +EVT_MOVING = wx.PyEventBinder( wxEVT_MOVING ) +EVT_MOVE_START = wx.PyEventBinder( wxEVT_MOVE_START ) +EVT_MOVE_END = wx.PyEventBinder( wxEVT_MOVE_END ) +EVT_CLOSE = wx.PyEventBinder( wxEVT_CLOSE_WINDOW ) +EVT_END_SESSION = wx.PyEventBinder( wxEVT_END_SESSION ) +EVT_QUERY_END_SESSION = wx.PyEventBinder( wxEVT_QUERY_END_SESSION ) +EVT_PAINT = wx.PyEventBinder( wxEVT_PAINT ) +EVT_NC_PAINT = wx.PyEventBinder( wxEVT_NC_PAINT ) +EVT_ERASE_BACKGROUND = wx.PyEventBinder( wxEVT_ERASE_BACKGROUND ) +EVT_CHAR = wx.PyEventBinder( wxEVT_CHAR ) +EVT_KEY_DOWN = wx.PyEventBinder( wxEVT_KEY_DOWN ) +EVT_KEY_UP = wx.PyEventBinder( wxEVT_KEY_UP ) +EVT_HOTKEY = wx.PyEventBinder( wxEVT_HOTKEY, 1) +EVT_CHAR_HOOK = wx.PyEventBinder( wxEVT_CHAR_HOOK ) +EVT_MENU_OPEN = wx.PyEventBinder( wxEVT_MENU_OPEN ) +EVT_MENU_CLOSE = wx.PyEventBinder( wxEVT_MENU_CLOSE ) +EVT_MENU_HIGHLIGHT = wx.PyEventBinder( wxEVT_MENU_HIGHLIGHT, 1) +EVT_MENU_HIGHLIGHT_ALL = wx.PyEventBinder( wxEVT_MENU_HIGHLIGHT ) +EVT_SET_FOCUS = wx.PyEventBinder( wxEVT_SET_FOCUS ) +EVT_KILL_FOCUS = wx.PyEventBinder( wxEVT_KILL_FOCUS ) +EVT_CHILD_FOCUS = wx.PyEventBinder( wxEVT_CHILD_FOCUS ) +EVT_ACTIVATE = wx.PyEventBinder( wxEVT_ACTIVATE ) +EVT_ACTIVATE_APP = wx.PyEventBinder( wxEVT_ACTIVATE_APP ) +EVT_HIBERNATE = wx.PyEventBinder( wxEVT_HIBERNATE ) +EVT_END_SESSION = wx.PyEventBinder( wxEVT_END_SESSION ) +EVT_QUERY_END_SESSION = wx.PyEventBinder( wxEVT_QUERY_END_SESSION ) +EVT_DROP_FILES = wx.PyEventBinder( wxEVT_DROP_FILES ) +EVT_INIT_DIALOG = wx.PyEventBinder( wxEVT_INIT_DIALOG ) +EVT_SYS_COLOUR_CHANGED = wx.PyEventBinder( wxEVT_SYS_COLOUR_CHANGED ) +EVT_DISPLAY_CHANGED = wx.PyEventBinder( wxEVT_DISPLAY_CHANGED ) +EVT_SHOW = wx.PyEventBinder( wxEVT_SHOW ) +EVT_MAXIMIZE = wx.PyEventBinder( wxEVT_MAXIMIZE ) +EVT_ICONIZE = wx.PyEventBinder( wxEVT_ICONIZE ) +EVT_NAVIGATION_KEY = wx.PyEventBinder( wxEVT_NAVIGATION_KEY ) +EVT_PALETTE_CHANGED = wx.PyEventBinder( wxEVT_PALETTE_CHANGED ) +EVT_QUERY_NEW_PALETTE = wx.PyEventBinder( wxEVT_QUERY_NEW_PALETTE ) +EVT_WINDOW_CREATE = wx.PyEventBinder( wxEVT_CREATE ) +EVT_WINDOW_DESTROY = wx.PyEventBinder( wxEVT_DESTROY ) +EVT_SET_CURSOR = wx.PyEventBinder( wxEVT_SET_CURSOR ) +EVT_MOUSE_CAPTURE_CHANGED = wx.PyEventBinder( wxEVT_MOUSE_CAPTURE_CHANGED ) +EVT_MOUSE_CAPTURE_LOST = wx.PyEventBinder( wxEVT_MOUSE_CAPTURE_LOST ) + +EVT_LEFT_DOWN = wx.PyEventBinder( wxEVT_LEFT_DOWN ) +EVT_LEFT_UP = wx.PyEventBinder( wxEVT_LEFT_UP ) +EVT_MIDDLE_DOWN = wx.PyEventBinder( wxEVT_MIDDLE_DOWN ) +EVT_MIDDLE_UP = wx.PyEventBinder( wxEVT_MIDDLE_UP ) +EVT_RIGHT_DOWN = wx.PyEventBinder( wxEVT_RIGHT_DOWN ) +EVT_RIGHT_UP = wx.PyEventBinder( wxEVT_RIGHT_UP ) +EVT_MOTION = wx.PyEventBinder( wxEVT_MOTION ) +EVT_LEFT_DCLICK = wx.PyEventBinder( wxEVT_LEFT_DCLICK ) +EVT_MIDDLE_DCLICK = wx.PyEventBinder( wxEVT_MIDDLE_DCLICK ) +EVT_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_RIGHT_DCLICK ) +EVT_LEAVE_WINDOW = wx.PyEventBinder( wxEVT_LEAVE_WINDOW ) +EVT_ENTER_WINDOW = wx.PyEventBinder( wxEVT_ENTER_WINDOW ) +EVT_MOUSEWHEEL = wx.PyEventBinder( wxEVT_MOUSEWHEEL ) +EVT_MOUSE_AUX1_DOWN = wx.PyEventBinder( wxEVT_AUX1_DOWN ) +EVT_MOUSE_AUX1_UP = wx.PyEventBinder( wxEVT_AUX1_UP ) +EVT_MOUSE_AUX1_DCLICK = wx.PyEventBinder( wxEVT_AUX1_DCLICK ) +EVT_MOUSE_AUX2_DOWN = wx.PyEventBinder( wxEVT_AUX2_DOWN ) +EVT_MOUSE_AUX2_UP = wx.PyEventBinder( wxEVT_AUX2_UP ) +EVT_MOUSE_AUX2_DCLICK = wx.PyEventBinder( wxEVT_AUX2_DCLICK ) + +EVT_MOUSE_EVENTS = wx.PyEventBinder([ wxEVT_LEFT_DOWN, + wxEVT_LEFT_UP, + wxEVT_MIDDLE_DOWN, + wxEVT_MIDDLE_UP, + wxEVT_RIGHT_DOWN, + wxEVT_RIGHT_UP, + wxEVT_MOTION, + wxEVT_LEFT_DCLICK, + wxEVT_MIDDLE_DCLICK, + wxEVT_RIGHT_DCLICK, + wxEVT_ENTER_WINDOW, + wxEVT_LEAVE_WINDOW, + wxEVT_MOUSEWHEEL, + wxEVT_AUX1_DOWN, + wxEVT_AUX1_UP, + wxEVT_AUX1_DCLICK, + wxEVT_AUX2_DOWN, + wxEVT_AUX2_UP, + wxEVT_AUX2_DCLICK, + ]) + + +# Scrolling from wxWindow (sent to wxScrolledWindow) +EVT_SCROLLWIN = wx.PyEventBinder([ wxEVT_SCROLLWIN_TOP, + wxEVT_SCROLLWIN_BOTTOM, + wxEVT_SCROLLWIN_LINEUP, + wxEVT_SCROLLWIN_LINEDOWN, + wxEVT_SCROLLWIN_PAGEUP, + wxEVT_SCROLLWIN_PAGEDOWN, + wxEVT_SCROLLWIN_THUMBTRACK, + wxEVT_SCROLLWIN_THUMBRELEASE, + ]) + +EVT_SCROLLWIN_TOP = wx.PyEventBinder( wxEVT_SCROLLWIN_TOP ) +EVT_SCROLLWIN_BOTTOM = wx.PyEventBinder( wxEVT_SCROLLWIN_BOTTOM ) +EVT_SCROLLWIN_LINEUP = wx.PyEventBinder( wxEVT_SCROLLWIN_LINEUP ) +EVT_SCROLLWIN_LINEDOWN = wx.PyEventBinder( wxEVT_SCROLLWIN_LINEDOWN ) +EVT_SCROLLWIN_PAGEUP = wx.PyEventBinder( wxEVT_SCROLLWIN_PAGEUP ) +EVT_SCROLLWIN_PAGEDOWN = wx.PyEventBinder( wxEVT_SCROLLWIN_PAGEDOWN ) +EVT_SCROLLWIN_THUMBTRACK = wx.PyEventBinder( wxEVT_SCROLLWIN_THUMBTRACK ) +EVT_SCROLLWIN_THUMBRELEASE = wx.PyEventBinder( wxEVT_SCROLLWIN_THUMBRELEASE ) + +# Scrolling from wx.Slider and wx.ScrollBar +EVT_SCROLL = wx.PyEventBinder([ wxEVT_SCROLL_TOP, + wxEVT_SCROLL_BOTTOM, + wxEVT_SCROLL_LINEUP, + wxEVT_SCROLL_LINEDOWN, + wxEVT_SCROLL_PAGEUP, + wxEVT_SCROLL_PAGEDOWN, + wxEVT_SCROLL_THUMBTRACK, + wxEVT_SCROLL_THUMBRELEASE, + wxEVT_SCROLL_CHANGED, + ]) + +EVT_SCROLL_TOP = wx.PyEventBinder( wxEVT_SCROLL_TOP ) +EVT_SCROLL_BOTTOM = wx.PyEventBinder( wxEVT_SCROLL_BOTTOM ) +EVT_SCROLL_LINEUP = wx.PyEventBinder( wxEVT_SCROLL_LINEUP ) +EVT_SCROLL_LINEDOWN = wx.PyEventBinder( wxEVT_SCROLL_LINEDOWN ) +EVT_SCROLL_PAGEUP = wx.PyEventBinder( wxEVT_SCROLL_PAGEUP ) +EVT_SCROLL_PAGEDOWN = wx.PyEventBinder( wxEVT_SCROLL_PAGEDOWN ) +EVT_SCROLL_THUMBTRACK = wx.PyEventBinder( wxEVT_SCROLL_THUMBTRACK ) +EVT_SCROLL_THUMBRELEASE = wx.PyEventBinder( wxEVT_SCROLL_THUMBRELEASE ) +EVT_SCROLL_CHANGED = wx.PyEventBinder( wxEVT_SCROLL_CHANGED ) +EVT_SCROLL_ENDSCROLL = EVT_SCROLL_CHANGED + +# Scrolling from wx.Slider and wx.ScrollBar, with an id +EVT_COMMAND_SCROLL = wx.PyEventBinder([ wxEVT_SCROLL_TOP, + wxEVT_SCROLL_BOTTOM, + wxEVT_SCROLL_LINEUP, + wxEVT_SCROLL_LINEDOWN, + wxEVT_SCROLL_PAGEUP, + wxEVT_SCROLL_PAGEDOWN, + wxEVT_SCROLL_THUMBTRACK, + wxEVT_SCROLL_THUMBRELEASE, + wxEVT_SCROLL_CHANGED, + ], 1) + +EVT_COMMAND_SCROLL_TOP = wx.PyEventBinder( wxEVT_SCROLL_TOP, 1) +EVT_COMMAND_SCROLL_BOTTOM = wx.PyEventBinder( wxEVT_SCROLL_BOTTOM, 1) +EVT_COMMAND_SCROLL_LINEUP = wx.PyEventBinder( wxEVT_SCROLL_LINEUP, 1) +EVT_COMMAND_SCROLL_LINEDOWN = wx.PyEventBinder( wxEVT_SCROLL_LINEDOWN, 1) +EVT_COMMAND_SCROLL_PAGEUP = wx.PyEventBinder( wxEVT_SCROLL_PAGEUP, 1) +EVT_COMMAND_SCROLL_PAGEDOWN = wx.PyEventBinder( wxEVT_SCROLL_PAGEDOWN, 1) +EVT_COMMAND_SCROLL_THUMBTRACK = wx.PyEventBinder( wxEVT_SCROLL_THUMBTRACK, 1) +EVT_COMMAND_SCROLL_THUMBRELEASE = wx.PyEventBinder( wxEVT_SCROLL_THUMBRELEASE, 1) +EVT_COMMAND_SCROLL_CHANGED = wx.PyEventBinder( wxEVT_SCROLL_CHANGED, 1) +EVT_COMMAND_SCROLL_ENDSCROLL = EVT_COMMAND_SCROLL_CHANGED + +EVT_BUTTON = wx.PyEventBinder( wxEVT_COMMAND_BUTTON_CLICKED, 1) +EVT_CHECKBOX = wx.PyEventBinder( wxEVT_COMMAND_CHECKBOX_CLICKED, 1) +EVT_CHOICE = wx.PyEventBinder( wxEVT_COMMAND_CHOICE_SELECTED, 1) +EVT_LISTBOX = wx.PyEventBinder( wxEVT_COMMAND_LISTBOX_SELECTED, 1) +EVT_LISTBOX_DCLICK = wx.PyEventBinder( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, 1) +EVT_MENU = wx.PyEventBinder( wxEVT_COMMAND_MENU_SELECTED, 1) +EVT_MENU_RANGE = wx.PyEventBinder( wxEVT_COMMAND_MENU_SELECTED, 2) +EVT_SLIDER = wx.PyEventBinder( wxEVT_COMMAND_SLIDER_UPDATED, 1) +EVT_RADIOBOX = wx.PyEventBinder( wxEVT_COMMAND_RADIOBOX_SELECTED, 1) +EVT_RADIOBUTTON = wx.PyEventBinder( wxEVT_COMMAND_RADIOBUTTON_SELECTED, 1) + +EVT_SCROLLBAR = wx.PyEventBinder( wxEVT_COMMAND_SCROLLBAR_UPDATED, 1) +EVT_VLBOX = wx.PyEventBinder( wxEVT_COMMAND_VLBOX_SELECTED, 1) +EVT_COMBOBOX = wx.PyEventBinder( wxEVT_COMMAND_COMBOBOX_SELECTED, 1) +EVT_TOOL = wx.PyEventBinder( wxEVT_COMMAND_TOOL_CLICKED, 1) +EVT_TOOL_RANGE = wx.PyEventBinder( wxEVT_COMMAND_TOOL_CLICKED, 2) +EVT_TOOL_RCLICKED = wx.PyEventBinder( wxEVT_COMMAND_TOOL_RCLICKED, 1) +EVT_TOOL_RCLICKED_RANGE = wx.PyEventBinder( wxEVT_COMMAND_TOOL_RCLICKED, 2) +EVT_TOOL_ENTER = wx.PyEventBinder( wxEVT_COMMAND_TOOL_ENTER, 1) +EVT_TOOL_DROPDOWN = wx.PyEventBinder( wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, 1) +EVT_CHECKLISTBOX = wx.PyEventBinder( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, 1) +EVT_COMBOBOX_DROPDOWN = wx.PyEventBinder( wxEVT_COMMAND_COMBOBOX_DROPDOWN , 1) +EVT_COMBOBOX_CLOSEUP = wx.PyEventBinder( wxEVT_COMMAND_COMBOBOX_CLOSEUP , 1) + +EVT_COMMAND_LEFT_CLICK = wx.PyEventBinder( wxEVT_COMMAND_LEFT_CLICK, 1) +EVT_COMMAND_LEFT_DCLICK = wx.PyEventBinder( wxEVT_COMMAND_LEFT_DCLICK, 1) +EVT_COMMAND_RIGHT_CLICK = wx.PyEventBinder( wxEVT_COMMAND_RIGHT_CLICK, 1) +EVT_COMMAND_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_COMMAND_RIGHT_DCLICK, 1) +EVT_COMMAND_SET_FOCUS = wx.PyEventBinder( wxEVT_COMMAND_SET_FOCUS, 1) +EVT_COMMAND_KILL_FOCUS = wx.PyEventBinder( wxEVT_COMMAND_KILL_FOCUS, 1) +EVT_COMMAND_ENTER = wx.PyEventBinder( wxEVT_COMMAND_ENTER, 1) + +EVT_IDLE = wx.PyEventBinder( wxEVT_IDLE ) + +EVT_UPDATE_UI = wx.PyEventBinder( wxEVT_UPDATE_UI, 1) +EVT_UPDATE_UI_RANGE = wx.PyEventBinder( wxEVT_UPDATE_UI, 2) + +EVT_CONTEXT_MENU = wx.PyEventBinder( wxEVT_CONTEXT_MENU ) + +EVT_TEXT_CUT = wx.PyEventBinder( wxEVT_COMMAND_TEXT_CUT ) +EVT_TEXT_COPY = wx.PyEventBinder( wxEVT_COMMAND_TEXT_COPY ) +EVT_TEXT_PASTE = wx.PyEventBinder( wxEVT_COMMAND_TEXT_PASTE ) + +EVT_THREAD = wx.PyEventBinder( wxEVT_COMMAND_THREAD ) + +# End of included code block +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +%End + //--------------------------------------------------------------------------- diff --git a/sip/gen/font.sip b/sip/gen/font.sip index 80af9180..a78bd560 100644 --- a/sip/gen/font.sip +++ b/sip/gen/font.sip @@ -207,25 +207,15 @@ public: ); %Property(name=Encoding, get=GetEncoding, set=SetEncoding) - %Property(name=FaceName, get=GetFaceName, set=SetFaceName) - %Property(name=Family, get=GetFamily, set=SetFamily) - %Property(name=NativeFontInfoDesc, get=GetNativeFontInfoDesc, set=SetNativeFontInfo) - %Property(name=NativeFontInfoUserDesc, get=GetNativeFontInfoUserDesc, set=SetNativeFontInfoUserDesc) - %Property(name=PointSize, get=GetPointSize, set=SetPointSize) - %Property(name=PixelSize, get=GetPixelSize, set=SetPixelSize) - %Property(name=Style, get=GetStyle, set=SetStyle) - %Property(name=Underlined, get=GetUnderlined, set=SetUnderlined) - %Property(name=Weight, get=GetWeight, set=SetWeight) - }; // end of class wxFont diff --git a/sip/gen/frame.sip b/sip/gen/frame.sip new file mode 100644 index 00000000..88fedc61 --- /dev/null +++ b/sip/gen/frame.sip @@ -0,0 +1,172 @@ +//--------------------------------------------------------------------------- +// This file is generated by wxPython's SIP generator. Do not edit by hand. +// +// Copyright: (c) 2010 by Total Control Software +// License: wxWindows License +// +// This file will be included by _core.sip +// +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- + +class wxFrame : wxTopLevelWindow +{ + %TypeHeaderCode + #include + %End + + +public: + wxFrame(); + + wxFrame( + wxWindow * parent /TranserThis/, + wxWindowID id = wxID_ANY, + const wxString & title = wxEmptyString, + const wxPoint & pos = wxDefaultPosition, + const wxSize & size = wxDefaultSize, + long style = wxDEFAULT_FRAME_STYLE, + const wxString & name = wxFrameNameStr + ); + + ~wxFrame(); + + void Centre( + int direction = wxBOTH + ); + + bool Create( + wxWindow * parent /TranserThis/, + wxWindowID id = wxID_ANY, + const wxString & title = wxEmptyString, + const wxPoint & pos = wxDefaultPosition, + const wxSize & size = wxDefaultSize, + long style = wxDEFAULT_FRAME_STYLE, + const wxString & name = wxFrameNameStr + ); + + wxStatusBar * CreateStatusBar( + int number = 1, + long style = wxSTB_DEFAULT_STYLE, + wxWindowID id = 0, + const wxString & name = wxStatusLineNameStr + ); + + wxToolBar * CreateToolBar( + long style = wxBORDER_NONE|wxTB_HORIZONTAL, + wxWindowID id = wxID_ANY, + const wxString & name = wxToolBarNameStr + ); + + virtual + wxPoint GetClientAreaOrigin(); + + wxMenuBar * GetMenuBar(); + + wxStatusBar * GetStatusBar(); + + int GetStatusBarPane(); + + wxToolBar * GetToolBar(); + + virtual + wxStatusBar * OnCreateStatusBar( + int number, + long style, + wxWindowID id, + const wxString & name + ); + + virtual + wxToolBar * OnCreateToolBar( + long style, + wxWindowID id, + const wxString & name + ); + + bool ProcessCommand( + int id + ); + + void SetMenuBar( + wxMenuBar * menuBar + ); + + void SetStatusBar( + wxStatusBar * statusBar + ); + + void SetStatusBarPane( + int n + ); + + void SetStatusText( + const wxString & text, + int number = 0 + ); + + void SetStatusWidths( + int n /ArraySize/, + const int * widths_field /Array/ + ); + + void SetToolBar( + wxToolBar * toolBar + ); + + void PushStatusText( + const wxString & text, + int number = 0 + ); + + void PopStatusText( + int number = 0 + ); + + %Property(name=MenuBar, get=GetMenuBar, set=SetMenuBar) + %Property(name=StatusBar, get=GetStatusBar, set=SetStatusBar) + %Property(name=StatusBarPane, get=GetStatusBarPane, set=SetStatusBarPane) + %Property(name=ToolBar, get=GetToolBar, set=SetToolBar) + public: + virtual bool Validate(); + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + virtual void InitDialog(); + virtual bool AcceptsFocus() const; + virtual bool AcceptsFocusRecursively() const; + virtual bool AcceptsFocusFromKeyboard() const; + virtual void AddChild( wxWindowBase *child ); + virtual void RemoveChild( wxWindowBase *child ); + virtual void InheritAttributes(); + virtual bool ShouldInheritColours() const; + virtual bool HasTransparentBackground(); + virtual void OnInternalIdle(); + virtual wxWindow *GetMainWindowOfCompositeControl(); + + + protected: + virtual bool ProcessEvent(wxEvent & event); + virtual void DoEnable(bool enable); + virtual void OnEnabled(bool enabled); + virtual void DoGetPosition(int *x, int *y) const; + virtual void DoGetSize(int *width, int *height) const; + virtual void DoGetClientSize(int *width, int *height) const; + virtual wxSize DoGetBestSize() const; + virtual wxSize DoGetBestClientSize() const; + virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags); + virtual void DoSetClientSize(int width, int height); + virtual void DoSetSizeHints( int minW, int minH, int maxW, int maxH, int incW, int incH ); + virtual wxSize DoGetBorderSize() const; + virtual void DoMoveWindow(int x, int y, int width, int height); + virtual void DoSetWindowVariant( wxWindowVariant variant); + virtual wxBorder GetDefaultBorder() const; + virtual wxBorder GetDefaultBorderForControl() const; + + +}; // end of class wxFrame + + + +//--------------------------------------------------------------------------- + diff --git a/sip/gen/gdicmn.sip b/sip/gen/gdicmn.sip index a456be25..17b56a83 100644 --- a/sip/gen/gdicmn.sip +++ b/sip/gen/gdicmn.sip @@ -286,9 +286,7 @@ public: ); %Property(name=width, get=GetWidth, set=SetWidth) - %Property(name=height, get=GetHeight, set=SetHeight) - %TypeCode PyObject* _wxSize_Get(wxSize* self, int& _isErr) { @@ -575,21 +573,13 @@ public: ); %Property(name=left, get=GetLeft) - %Property(name=top, get=GetTop) - %Property(name=right, get=GetRight) - %Property(name=bottom, get=GetBottom) - %Property(name=bottomLeft, get=GetBottomLeft) - %Property(name=bottomRight, get=GetBottomRight) - %Property(name=topLeft, get=GetTopLeft) - %Property(name=topRight, get=GetTopRight) - %TypeCode PyObject* _wxRect_Get(wxRect* self, int& _isErr) { diff --git a/sip/gen/kbdstate.sip b/sip/gen/kbdstate.sip index f5d91ba5..b406671a 100644 --- a/sip/gen/kbdstate.sip +++ b/sip/gen/kbdstate.sip @@ -56,15 +56,10 @@ public: ); %Property(name=controlDown, get=ControlDown, set=SetControlDown) - %Property(name=shiftDown, get=ShiftDown, set=SetShiftDown) - %Property(name=altDown, get=AltDown, set=SetAltDown) - %Property(name=metaDown, get=MetaDown, set=SetMetaDown) - %Property(name=cmdDown, get=CmdDown) - }; // end of class wxKeyboardState diff --git a/sip/gen/layout.sip b/sip/gen/layout.sip index bf2bec32..b8f3be73 100644 --- a/sip/gen/layout.sip +++ b/sip/gen/layout.sip @@ -126,21 +126,13 @@ public: ); %Property(name=Done, get=GetDone, set=SetDone) - %Property(name=Margin, get=GetMargin, set=SetMargin) - %Property(name=MyEdge, get=GetMyEdge) - %Property(name=OtherEdge, get=GetOtherEdge) - %Property(name=OtherWindow, get=GetOtherWindow) - %Property(name=Percent, get=GetPercent) - %Property(name=Relationship, get=GetRelationship, set=SetRelationship) - %Property(name=Value, get=GetValue, set=SetValue) - }; // end of class wxIndividualLayoutConstraint diff --git a/sip/gen/mousestate.sip b/sip/gen/mousestate.sip index cc761487..c9234160 100644 --- a/sip/gen/mousestate.sip +++ b/sip/gen/mousestate.sip @@ -73,21 +73,13 @@ public: ); %Property(name=x, get=GetX, set=SetX) - %Property(name=y, get=GetY, set=SetY) - %Property(name=leftIsDown, get=LeftIsDown, set=SetLeftDown) - %Property(name=middleIsDown, get=MiddleIsDown, set=SetMiddleDown) - %Property(name=rightIsDown, get=RightIsDown, set=SetRightDown) - %Property(name=aux1IsDown, get=Aux1IsDown, set=SetAux1Down) - %Property(name=aux2IsDown, get=Aux2IsDown, set=SetAux2Down) - %Property(name=Position, get=GetPosition, set=SetPosition) - }; // end of class wxMouseState diff --git a/sip/gen/object.sip b/sip/gen/object.sip index 0c5e605c..7a520287 100644 --- a/sip/gen/object.sip +++ b/sip/gen/object.sip @@ -26,6 +26,10 @@ public: void IncRef(); + private: + wxRefCounter(const wxRefCounter&); + + protected: virtual diff --git a/sip/gen/region.sip b/sip/gen/region.sip index 524e78b2..3990d42c 100644 --- a/sip/gen/region.sip +++ b/sip/gen/region.sip @@ -71,19 +71,12 @@ public: %End %Property(name=H, get=GetH) - %Property(name=Height, get=GetHeight) - %Property(name=Rect, get=GetRect) - %Property(name=W, get=GetW) - %Property(name=Width, get=GetWidth) - %Property(name=X, get=GetX) - %Property(name=Y, get=GetY) - }; // end of class wxRegionIterator @@ -240,7 +233,6 @@ public: ); %Property(name=Box, get=GetBox) - }; // end of class wxRegion diff --git a/sip/gen/tooltip.sip b/sip/gen/tooltip.sip index cb437938..36ac3551 100644 --- a/sip/gen/tooltip.sip +++ b/sip/gen/tooltip.sip @@ -51,8 +51,10 @@ public: ); %Property(name=Tip, get=GetTip, set=SetTip) - %Property(name=Window, get=GetWindow) + private: + wxToolTip(const wxToolTip&); + }; // end of class wxToolTip diff --git a/sip/gen/toplevel.sip b/sip/gen/toplevel.sip index 005c1cfe..9bb52e58 100644 --- a/sip/gen/toplevel.sip +++ b/sip/gen/toplevel.sip @@ -30,7 +30,6 @@ public: const wxString & name = wxFrameNameStr ); - virtual ~wxTopLevelWindow(); bool Create( @@ -43,7 +42,6 @@ public: const wxString & name = wxFrameNameStr ); - virtual bool CanSetTransparent(); void CenterOnScreen( @@ -54,7 +52,6 @@ public: int direction = wxBOTH ); - virtual bool EnableCloseButton( bool enable = true ); @@ -65,38 +62,28 @@ public: const wxIconBundle & GetIcons(); - virtual wxString GetTitle(); - virtual void Iconize( bool iconize = true ); - virtual bool IsActive(); - virtual bool IsAlwaysMaximized(); - virtual bool IsFullScreen(); - virtual bool IsIconized(); - virtual bool IsMaximized(); - virtual bool Layout(); - virtual void Maximize( bool maximize = true ); - virtual void RequestUserAttention( int flags = wxUSER_ATTENTION_INFO ); @@ -115,27 +102,22 @@ public: const wxIcon & icon ); - virtual void SetIcons( const wxIconBundle & icons ); - virtual void SetMaxSize( const wxSize & size ); - virtual void SetMinSize( const wxSize & size ); - virtual bool SetShape( const wxRegion & region ); - virtual void SetSizeHints( int minW, int minH, @@ -145,35 +127,28 @@ public: int incH = -1 ); - virtual void SetSizeHints( const wxSize & minSize, const wxSize & maxSize = wxDefaultSize, const wxSize & incSize = wxDefaultSize ); - virtual void SetTitle( const wxString & title ); - virtual bool SetTransparent( wxByte alpha ); - virtual bool ShouldPreventAppExit(); - virtual void OSXSetModified( bool modified ); - virtual bool OSXIsModified(); - virtual bool ShowFullScreen( bool show, long style = wxFULLSCREEN_ALL @@ -236,14 +211,46 @@ public: %End %Property(name=DefaultItem, get=GetDefaultItem, set=SetDefaultItem) - %Property(name=Icon, get=GetIcon, set=SetIcon) - %Property(name=Title, get=GetTitle, set=SetTitle) - %Property(name=TmpDefaultItem, get=GetTmpDefaultItem, set=SetTmpDefaultItem) - %Property(name=OSXModified, get=OSXIsModified, set=OSXSetModified) + public: + virtual wxPoint GetClientAreaOrigin() const; + virtual bool Validate(); + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + virtual void InitDialog(); + virtual bool AcceptsFocus() const; + virtual bool AcceptsFocusRecursively() const; + virtual bool AcceptsFocusFromKeyboard() const; + virtual void AddChild( wxWindowBase *child ); + virtual void RemoveChild( wxWindowBase *child ); + virtual void InheritAttributes(); + virtual bool ShouldInheritColours() const; + virtual bool HasTransparentBackground(); + virtual void OnInternalIdle(); + virtual wxWindow *GetMainWindowOfCompositeControl(); + + + protected: + virtual bool ProcessEvent(wxEvent & event); + virtual void DoEnable(bool enable); + virtual void OnEnabled(bool enabled); + virtual void DoGetPosition(int *x, int *y) const; + virtual void DoGetSize(int *width, int *height) const; + virtual void DoGetClientSize(int *width, int *height) const; + virtual wxSize DoGetBestSize() const; + virtual wxSize DoGetBestClientSize() const; + virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags); + virtual void DoSetClientSize(int width, int height); + virtual void DoSetSizeHints( int minW, int minH, int maxW, int maxH, int incW, int incH ); + virtual wxSize DoGetBorderSize() const; + virtual void DoMoveWindow(int x, int y, int width, int height); + virtual void DoSetWindowVariant( wxWindowVariant variant); + virtual wxBorder GetDefaultBorder() const; + virtual wxBorder GetDefaultBorderForControl() const; + }; // end of class wxTopLevelWindow diff --git a/sip/gen/window.sip b/sip/gen/window.sip index 3b60706a..7043d68c 100644 --- a/sip/gen/window.sip +++ b/sip/gen/window.sip @@ -25,7 +25,15 @@ struct wxVisualAttributes }; // end of class wxVisualAttributes -class wxWindow : wxEvtHandler + class wxWindowBase : wxEvtHandler /Abstract/ + { + public: + virtual void AddChild( wxWindowBase* child ); + virtual void RemoveChild( wxWindowBase* child ); + }; + + +class wxWindow : wxWindowBase { %TypeHeaderCode #include @@ -76,7 +84,6 @@ public: const wxString & name = wxPanelNameStr ); - virtual ~wxWindow(); virtual @@ -88,23 +95,19 @@ public: virtual bool AcceptsFocusRecursively(); - virtual bool HasFocus(); - virtual void SetCanFocus( bool canFocus ); - virtual void SetFocus(); - virtual void SetFocusFromKbd(); virtual void AddChild( - wxWindow * child + wxWindowBase* child ); bool DestroyChildren(); @@ -121,7 +124,7 @@ public: virtual void RemoveChild( - wxWindow * child + wxWindowBase* child ); wxWindow * GetGrandParent(); @@ -132,28 +135,23 @@ public: wxWindow * GetPrevSibling(); - virtual bool Reparent( wxWindow * newParent ); - virtual void AlwaysShowScrollbars( bool hflag = true, bool vflag = true ); - virtual int GetScrollPos( int orientation ); - virtual int GetScrollRange( int orientation ); - virtual int GetScrollThumb( int orientation ); @@ -166,22 +164,18 @@ public: int orient ); - virtual bool IsScrollbarAlwaysShown( int orient ); - virtual bool ScrollLines( int lines ); - virtual bool ScrollPages( int pages ); - virtual void ScrollWindow( int dx, int dy, @@ -196,14 +190,12 @@ public: bool PageDown(); - virtual void SetScrollPos( int orientation, int pos, bool refresh = true ); - virtual void SetScrollbar( int orientation, int position, @@ -216,39 +208,30 @@ public: const wxSize & size ); - virtual wxSize ClientToWindowSize( const wxSize & size ); - virtual wxSize WindowToClientSize( const wxSize & size ); - virtual void Fit(); - virtual void FitInside(); wxSize GetBestSize(); wxSize GetClientSize(); - virtual wxSize GetEffectiveMinSize(); - virtual wxSize GetMaxClientSize(); - virtual wxSize GetMaxSize(); - virtual wxSize GetMinClientSize(); - virtual wxSize GetMinSize(); int GetMinWidth(); @@ -263,13 +246,10 @@ public: wxSize GetVirtualSize(); - virtual wxSize GetBestVirtualSize(); - virtual wxSize GetWindowBorderSize(); - virtual bool InformFirstDirection( int direction, int size, @@ -282,7 +262,6 @@ public: void PostSizeEventToParent(); - virtual void SendSizeEvent( int flags = 0 ); @@ -312,22 +291,18 @@ public: const wxSize & size = wxDefaultSize ); - virtual void SetMaxClientSize( const wxSize & size ); - virtual void SetMaxSize( const wxSize & size ); - virtual void SetMinClientSize( const wxSize & size ); - virtual void SetMinSize( const wxSize & size ); @@ -353,14 +328,12 @@ public: int height ); - virtual void SetSizeHints( const wxSize & minSize, const wxSize & maxSize = wxDefaultSize, const wxSize & incSize = wxDefaultSize ); - virtual void SetSizeHints( int minW, int minH, @@ -447,7 +420,6 @@ public: const wxPoint & pt ); - virtual void ClearBackground(); void Freeze(); @@ -458,16 +430,12 @@ public: wxColour GetBackgroundColour(); - virtual wxBackgroundStyle GetBackgroundStyle(); - virtual int GetCharHeight(); - virtual int GetCharWidth(); - virtual wxVisualAttributes GetDefaultAttributes(); wxFont GetFont(); @@ -494,7 +462,6 @@ public: virtual bool HasTransparentBackground(); - virtual void Refresh( bool eraseBackground = true, const wxRect * rect = NULL @@ -505,25 +472,20 @@ public: bool eraseBackground = true ); - virtual void Update(); - virtual bool SetBackgroundColour( const wxColour & colour ); - virtual bool SetBackgroundStyle( wxBackgroundStyle style ); - virtual bool SetFont( const wxFont & font ); - virtual bool SetForegroundColour( const wxColour & colour ); @@ -547,18 +509,14 @@ public: virtual bool ShouldInheritColours(); - virtual void SetThemeEnabled( bool enable ); - virtual bool GetThemeEnabled(); - virtual bool CanSetTransparent(); - virtual bool SetTransparent( wxByte alpha ); @@ -597,19 +555,16 @@ public: wxEvtHandler * handler ); - virtual void SetNextHandler( wxEvtHandler * handler ); - virtual void SetPreviousHandler( wxEvtHandler * handler ); long GetExtraStyle(); - virtual long GetWindowStyleFlag(); long GetWindowStyle(); @@ -622,12 +577,10 @@ public: int flag ); - virtual void SetExtraStyle( long exStyle ); - virtual void SetWindowStyleFlag( long style ); @@ -656,15 +609,12 @@ public: int flags = wxNavigationKeyEvent::IsForward ); - virtual void Lower(); - virtual void Raise(); bool Hide(); - virtual bool HideWithEffect( wxShowEffect effect, unsigned int timeout = 0 @@ -692,25 +642,20 @@ public: wxRect & rect ); - virtual bool IsShown(); - virtual bool IsShownOnScreen(); bool Disable(); - virtual bool Enable( bool enable = true ); - virtual bool Show( bool show = true ); - virtual bool ShowWithEffect( wxShowEffect effect, unsigned int timeout = 0 @@ -722,7 +667,6 @@ public: const wxString & helpText ); - virtual wxString GetHelpTextAtPoint( const wxPoint & point, wxHelpEvent::Origin origin @@ -764,10 +708,8 @@ public: int y ); - virtual wxValidator * GetValidator(); - virtual void SetValidator( const wxValidator & validator ); @@ -783,13 +725,10 @@ public: wxWindowID GetId(); - virtual wxString GetLabel(); - virtual wxLayoutDirection GetLayoutDirection(); - virtual wxString GetName(); wxWindowVariant GetWindowVariant(); @@ -798,17 +737,14 @@ public: wxWindowID winid ); - virtual void SetLabel( const wxString & label ); - virtual void SetLayoutDirection( wxLayoutDirection dir ); - virtual void SetName( const wxString & name ); @@ -819,7 +755,6 @@ public: wxAcceleratorTable * GetAcceleratorTable(); - virtual void SetAcceleratorTable( const wxAcceleratorTable & accel ); @@ -828,20 +763,16 @@ public: bool force = false ); - virtual - bool Destroy(); + bool Destroy() /TranserThis/; bool IsBeingDeleted(); - virtual wxDropTarget * GetDropTarget(); - virtual void SetDropTarget( wxDropTarget * target /Transfer/ ); - virtual void DragAcceptFiles( bool accept ); @@ -866,7 +797,6 @@ public: wxLayoutConstraints * constraints /Transfer/ ); - virtual bool Layout(); void SetAutoLayout( @@ -881,7 +811,6 @@ public: const wxCursor & GetCursor(); - virtual bool HasCapture(); void ReleaseMouse(); @@ -890,12 +819,10 @@ public: wxCaret * caret /Transfer/ ); - virtual bool SetCursor( const wxCursor & cursor ); - virtual void WarpPointer( int x, int y @@ -916,18 +843,15 @@ public: wxBorder GetBorder(); - virtual void DoUpdateWindowUI( wxUpdateUIEvent & event ); - virtual void* GetHandle(); %MethodCode sipRes = wxPyGetWinHandle(sipCpp); %End - virtual bool HasMultiplePages(); virtual @@ -936,7 +860,6 @@ public: virtual void InitDialog(); - virtual bool IsDoubleBuffered(); void SetDoubleBuffered( @@ -948,15 +871,12 @@ public: #endif %End - virtual bool IsRetained(); bool IsThisEnabled(); - virtual bool IsTopLevel(); - virtual void MakeModal( bool modal = true ); @@ -988,7 +908,6 @@ public: #endif %End - virtual void UpdateWindowUI( long flags = wxUPDATE_UI_NONE ); @@ -1084,138 +1003,90 @@ public: %End %Property(name=AcceleratorTable, get=GetAcceleratorTable, set=SetAcceleratorTable) - %Property(name=AutoLayout, get=GetAutoLayout, set=SetAutoLayout) - %Property(name=BackgroundColour, get=GetBackgroundColour, set=SetBackgroundColour) - %Property(name=BackgroundStyle, get=GetBackgroundStyle, set=SetBackgroundStyle) - %Property(name=EffectiveMinSize, get=GetEffectiveMinSize) - %Property(name=BestSize, get=GetBestSize) - %Property(name=BestVirtualSize, get=GetBestVirtualSize) - %Property(name=Border, get=GetBorder) - %Property(name=Caret, get=GetCaret, set=SetCaret) - %Property(name=CharHeight, get=GetCharHeight) - %Property(name=CharWidth, get=GetCharWidth) - %Property(name=Children, get=GetChildren) - %Property(name=ClientAreaOrigin, get=GetClientAreaOrigin) - %Property(name=ClientRect, get=GetClientRect, set=SetClientRect) - %Property(name=ClientSize, get=GetClientSize, set=SetClientSize) - %Property(name=Constraints, get=GetConstraints, set=SetConstraints) - %Property(name=ContainingSizer, get=GetContainingSizer, set=SetContainingSizer) - %Property(name=Cursor, get=GetCursor, set=SetCursor) - %Property(name=DefaultAttributes, get=GetDefaultAttributes) - %Property(name=DropTarget, get=GetDropTarget, set=SetDropTarget) - %Property(name=EventHandler, get=GetEventHandler, set=SetEventHandler) - %Property(name=ExtraStyle, get=GetExtraStyle, set=SetExtraStyle) - %Property(name=Font, get=GetFont, set=SetFont) - %Property(name=ForegroundColour, get=GetForegroundColour, set=SetForegroundColour) - %Property(name=GrandParent, get=GetGrandParent) - %Property(name=TopLevelParent, get=GetTopLevelParent) - %Property(name=Handle, get=GetHandle) - %Property(name=HelpText, get=GetHelpText, set=SetHelpText) - %Property(name=Id, get=GetId, set=SetId) - %Property(name=Label, get=GetLabel, set=SetLabel) - %Property(name=LayoutDirection, get=GetLayoutDirection, set=SetLayoutDirection) - %Property(name=MaxHeight, get=GetMaxHeight) - %Property(name=MaxSize, get=GetMaxSize, set=SetMaxSize) - %Property(name=MaxWidth, get=GetMaxWidth) - %Property(name=MinHeight, get=GetMinHeight) - %Property(name=MinSize, get=GetMinSize, set=SetMinSize) - %Property(name=MinWidth, get=GetMinWidth) - %Property(name=Name, get=GetName, set=SetName) - %Property(name=Parent, get=GetParent) - %Property(name=Position, get=GetPosition, set=SetPosition) - %Property(name=Rect, get=GetRect, set=SetRect) - %Property(name=ScreenPosition, get=GetScreenPosition) - %Property(name=ScreenRect, get=GetScreenRect) - %Property(name=Size, get=GetSize, set=SetSize) - %Property(name=Sizer, get=GetSizer, set=SetSizer) - %Property(name=ThemeEnabled, get=GetThemeEnabled, set=SetThemeEnabled) - %Property(name=ToolTip, get=GetToolTip, set=SetToolTip) - %Property(name=UpdateClientRect, get=GetUpdateClientRect) - %Property(name=UpdateRegion, get=GetUpdateRegion) - %Property(name=Validator, get=GetValidator, set=SetValidator) - %Property(name=VirtualSize, get=GetVirtualSize, set=SetVirtualSize) - %Property(name=WindowStyle, get=GetWindowStyle, set=SetWindowStyle) - %Property(name=WindowStyleFlag, get=GetWindowStyleFlag, set=SetWindowStyleFlag) - %Property(name=WindowVariant, get=GetWindowVariant, set=SetWindowVariant) - %Property(name=Shown, get=IsShown, set=Show) - %Property(name=Enabled, get=IsEnabled, set=Enable) - %Property(name=TopLevel, get=IsTopLevel) - %Property(name=MinClientSize, get=GetMinClientSize, set=SetMinClientSize) - %Property(name=MaxClientSize, get=GetMaxClientSize, set=SetMaxClientSize) + public: + virtual wxWindow *GetMainWindowOfCompositeControl(); + + + protected: + virtual void DoEnable(bool enable); + virtual void OnEnabled(bool enabled); + virtual void DoGetPosition(int *x, int *y) const; + virtual void DoGetSize(int *width, int *height) const; + virtual void DoGetClientSize(int *width, int *height) const; + virtual wxSize DoGetBestClientSize() const; + virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags); + virtual void DoSetClientSize(int width, int height); + virtual void DoSetSizeHints( int minW, int minH, int maxW, int maxH, int incW, int incH ); + virtual wxSize DoGetBorderSize() const; + virtual void DoMoveWindow(int x, int y, int width, int height); + virtual void DoSetWindowVariant( wxWindowVariant variant); + virtual wxBorder GetDefaultBorder() const; + virtual wxBorder GetDefaultBorderForControl() const; + protected: - virtual - void DoCentre( - int direction - ); - virtual wxSize DoGetBestSize(); - virtual - void SetInitialBestSize( - const wxSize & size - ); - void SendDestroyEvent(); virtual @@ -1227,7 +1098,7 @@ protected: %Extract(id=pycode) -def _Window_PostCreate(): +def _Window_PostCreate(self, pre): pass Window.PostCreate = _Window_PostCreate del _Window_PostCreate @@ -1268,6 +1139,23 @@ wxWindow * wxGetTopLevelParent( wxWindow * window ); +%Extract(id=pycode) +class FrozenWindow(object): + """ + A context manager to be used with Python 'with' statements + that will freeze the given window for the duration of the + with block. + """ + def __init__(self, window): + self._win = window + def __enter__(self): + self._win.Freeze() + return self + def __exit__(self, exc_type, exc_val, exc_tb): + self._win.Thaw() + +%End + //--------------------------------------------------------------------------- diff --git a/sip/siplib/sip.h b/sip/siplib/sip.h index ea917104..5f13cdef 100644 --- a/sip/siplib/sip.h +++ b/sip/siplib/sip.h @@ -55,7 +55,7 @@ extern "C" { * Define the SIP version number. */ #define SIP_VERSION 0x040c00 -#define SIP_VERSION_STR "4.12-snapshot-b2f993d3a067" +#define SIP_VERSION_STR "4.12-snapshot-40a042b3abce" /* @@ -69,6 +69,7 @@ extern "C" { * History: * * 8.1 Revised the sipVariableDef structure. + * sip_api_get_address() is now part of the public API. * * 8.0 Changed the size of the sipSimpleWrapper structure. * Added sip_api_get_address(). @@ -1448,6 +1449,9 @@ typedef struct _sipAPIDef { PyObject *sipKwdArgs, const char **kwdlist, PyObject **unused, const char *fmt, ...); void (*api_add_exception)(sipErrorState es, PyObject **parseErrp); + /* + * The following are part of the public API. + */ void *(*api_get_address)(struct _sipSimpleWrapper *w); } sipAPIDef; diff --git a/sip/siplib/siplib.c b/sip/siplib/siplib.c index 27b25717..ce7873d4 100644 --- a/sip/siplib/siplib.c +++ b/sip/siplib/siplib.c @@ -363,6 +363,9 @@ static const sipAPIDef sip_api = { sip_api_keep_reference, sip_api_parse_kwd_args, sip_api_add_exception, + /* + * The following are part of the public API. + */ sip_api_get_address }; diff --git a/src/app_ex.cpp b/src/app_ex.cpp index e9f417af..1b177863 100644 --- a/src/app_ex.cpp +++ b/src/app_ex.cpp @@ -69,6 +69,7 @@ public: virtual void OnPreInit() { } void _BootstrapApp(); + virtual int MainLoop(); static bool IsDisplayAvailable(); @@ -93,32 +94,32 @@ 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 + + // Copy the values in Python's sys.argv list to a C array of char* to + // be passed to the wxEntryStart function below. 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; + if (sysargv != NULL) { + argc = PyList_Size(sysargv); argv = new char*[argc+1]; - argv[0] = strdup(PyString_AsString(executable)); int x; - for(x=1; xm_func; + PyObject* result; + PyObject* arg; + PyObject* tuple; + bool checkSkip = false; + + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + wxString className = event.GetClassInfo()->GetClassName(); + + // // If the event is one of these types then pass the original + // // event object instead of the one passed to us. + // if ( className == wxT("wxPyEvent") ) { + // arg = ((wxPyEvent*)&event)->GetSelf(); + // checkSkip = ((wxPyEvent*)&event)->GetCloned(); + // } + // else if ( className == wxT("wxPyCommandEvent") ) { + // arg = ((wxPyCommandEvent*)&event)->GetSelf(); + // checkSkip = ((wxPyCommandEvent*)&event)->GetCloned(); + // } + // else { + arg = wxPyConstructObject((void*)&event, className); + // } + + + if (!arg) { + PyErr_Print(); + } else { + // // "intern" the pre/post method names to speed up the HasAttr + // static PyObject* s_preName = NULL; + // static PyObject* s_postName = NULL; + // if (s_preName == NULL) { + // s_preName = PyString_FromString(wxPy_PRECALLINIT); + // s_postName = PyString_FromString(wxPy_POSTCALLCLEANUP); + // } + + // // Check if the event object needs some preinitialization + // if (PyObject_HasAttr(arg, s_preName)) { + // result = PyObject_CallMethodObjArgs(arg, s_preName, arg, NULL); + // if ( result ) { + // Py_DECREF(result); // result is ignored, but we still need to decref it + // PyErr_Clear(); // Just in case... + // } else { + // PyErr_Print(); + // } + // } + + // Call the event handler, passing the event object + tuple = PyTuple_New(1); + PyTuple_SET_ITEM(tuple, 0, arg); // steals ref to arg + result = PyEval_CallObject(func, tuple); + if ( result ) { + Py_DECREF(result); // result is ignored, but we still need to decref it + PyErr_Clear(); // Just in case... + } else { + PyErr_Print(); + } + + // // Check if the event object needs some post cleanup + // if (PyObject_HasAttr(arg, s_postName)) { + // result = PyObject_CallMethodObjArgs(arg, s_postName, arg, NULL); + // if ( result ) { + // Py_DECREF(result); // result is ignored, but we still need to decref it + // PyErr_Clear(); // Just in case... + // } else { + // PyErr_Print(); + // } + // } + + // if ( checkSkip ) { + // // if the event object was one of our special types and + // // it had been cloned, then we need to extract the Skipped + // // value from the original and set it in the clone. + // result = PyObject_CallMethod(arg, "GetSkipped", ""); + // if ( result ) { + // event.Skip(PyInt_AsLong(result)); + // Py_DECREF(result); + // } else { + // PyErr_Print(); + // } + // } + Py_DECREF(tuple); + } + wxPyEndBlockThreads(blocked); +} diff --git a/src/event_ex.py b/src/event_ex.py new file mode 100644 index 00000000..7dfdb7fa --- /dev/null +++ b/src/event_ex.py @@ -0,0 +1,285 @@ + +class PyEventBinder(object): + """ + Instances of this class are used to bind specific events to event + handlers. + """ + def __init__(self, evtType, expectedIDs=0): + if expectedIDs not in [0, 1, 2]: + raise ValueError, "Invalid number of expectedIDs" + self.expectedIDs = expectedIDs + + if isinstance(evtType, (list, tuple)): + self.evtType = list(evtType) + else: + self.evtType = [evtType] + + + def Bind(self, target, id1, id2, function): + """Bind this set of event types to target using its COnnect() method.""" + for et in self.evtType: + target.Connect(id1, id2, et, function) + + + def Unbind(self, target, id1, id2, handler=None): + """Remove an event binding.""" + success = 0 + for et in self.evtType: + success += target.Disconnect(id1, id2, et, handler) + return success != 0 + + + def _getEvtType(self): + """ + Make it easy to get to the default wxEventType typeID for this + event binder. + """ + return self.evtType[0] + typeId = property(_getEvtType) + + + +def _EvtHandler_Bind(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY): + """ + Bind an event to an event handler. + + :param event: One of the EVT_* objects that specifies the + type of event to bind, + + :param handler: A callable object to be invoked when the + event is delivered to self. Pass None to + disconnect an event handler. + + :param source: Sometimes the event originates from a + different window than self, but you still + want to catch it in self. (For example, a + button event delivered to a frame.) By + passing the source of the event, the event + handling system is able to differentiate + between the same event type from different + controls. + + :param id: Used to spcify the event source by ID instead + of instance. + + :param id2: Used when it is desirable to bind a handler + to a range of IDs, such as with EVT_MENU_RANGE. + """ + if source is not None: + id = source.GetId() + event.Bind(self, id, id2, handler) + + +def _EvtHandler_Unbind(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY, handler=None): + """ + Disconnects the event handler binding for event from self. + Returns True if successful. + """ + if source is not None: + id = source.GetId() + return event.Unbind(self, id, id2, handler) + + +EvtHandler.Bind = _EvtHandler_Bind +EvtHandler.Unbind = _EvtHandler_Unbind +del _EvtHandler_Bind, _EvtHandler_Unbind + + +# Create some event binders +EVT_SIZE = wx.PyEventBinder( wxEVT_SIZE ) +EVT_SIZING = wx.PyEventBinder( wxEVT_SIZING ) +EVT_MOVE = wx.PyEventBinder( wxEVT_MOVE ) +EVT_MOVING = wx.PyEventBinder( wxEVT_MOVING ) +EVT_MOVE_START = wx.PyEventBinder( wxEVT_MOVE_START ) +EVT_MOVE_END = wx.PyEventBinder( wxEVT_MOVE_END ) +EVT_CLOSE = wx.PyEventBinder( wxEVT_CLOSE_WINDOW ) +EVT_END_SESSION = wx.PyEventBinder( wxEVT_END_SESSION ) +EVT_QUERY_END_SESSION = wx.PyEventBinder( wxEVT_QUERY_END_SESSION ) +EVT_PAINT = wx.PyEventBinder( wxEVT_PAINT ) +EVT_NC_PAINT = wx.PyEventBinder( wxEVT_NC_PAINT ) +EVT_ERASE_BACKGROUND = wx.PyEventBinder( wxEVT_ERASE_BACKGROUND ) +EVT_CHAR = wx.PyEventBinder( wxEVT_CHAR ) +EVT_KEY_DOWN = wx.PyEventBinder( wxEVT_KEY_DOWN ) +EVT_KEY_UP = wx.PyEventBinder( wxEVT_KEY_UP ) +EVT_HOTKEY = wx.PyEventBinder( wxEVT_HOTKEY, 1) +EVT_CHAR_HOOK = wx.PyEventBinder( wxEVT_CHAR_HOOK ) +EVT_MENU_OPEN = wx.PyEventBinder( wxEVT_MENU_OPEN ) +EVT_MENU_CLOSE = wx.PyEventBinder( wxEVT_MENU_CLOSE ) +EVT_MENU_HIGHLIGHT = wx.PyEventBinder( wxEVT_MENU_HIGHLIGHT, 1) +EVT_MENU_HIGHLIGHT_ALL = wx.PyEventBinder( wxEVT_MENU_HIGHLIGHT ) +EVT_SET_FOCUS = wx.PyEventBinder( wxEVT_SET_FOCUS ) +EVT_KILL_FOCUS = wx.PyEventBinder( wxEVT_KILL_FOCUS ) +EVT_CHILD_FOCUS = wx.PyEventBinder( wxEVT_CHILD_FOCUS ) +EVT_ACTIVATE = wx.PyEventBinder( wxEVT_ACTIVATE ) +EVT_ACTIVATE_APP = wx.PyEventBinder( wxEVT_ACTIVATE_APP ) +EVT_HIBERNATE = wx.PyEventBinder( wxEVT_HIBERNATE ) +EVT_END_SESSION = wx.PyEventBinder( wxEVT_END_SESSION ) +EVT_QUERY_END_SESSION = wx.PyEventBinder( wxEVT_QUERY_END_SESSION ) +EVT_DROP_FILES = wx.PyEventBinder( wxEVT_DROP_FILES ) +EVT_INIT_DIALOG = wx.PyEventBinder( wxEVT_INIT_DIALOG ) +EVT_SYS_COLOUR_CHANGED = wx.PyEventBinder( wxEVT_SYS_COLOUR_CHANGED ) +EVT_DISPLAY_CHANGED = wx.PyEventBinder( wxEVT_DISPLAY_CHANGED ) +EVT_SHOW = wx.PyEventBinder( wxEVT_SHOW ) +EVT_MAXIMIZE = wx.PyEventBinder( wxEVT_MAXIMIZE ) +EVT_ICONIZE = wx.PyEventBinder( wxEVT_ICONIZE ) +EVT_NAVIGATION_KEY = wx.PyEventBinder( wxEVT_NAVIGATION_KEY ) +EVT_PALETTE_CHANGED = wx.PyEventBinder( wxEVT_PALETTE_CHANGED ) +EVT_QUERY_NEW_PALETTE = wx.PyEventBinder( wxEVT_QUERY_NEW_PALETTE ) +EVT_WINDOW_CREATE = wx.PyEventBinder( wxEVT_CREATE ) +EVT_WINDOW_DESTROY = wx.PyEventBinder( wxEVT_DESTROY ) +EVT_SET_CURSOR = wx.PyEventBinder( wxEVT_SET_CURSOR ) +EVT_MOUSE_CAPTURE_CHANGED = wx.PyEventBinder( wxEVT_MOUSE_CAPTURE_CHANGED ) +EVT_MOUSE_CAPTURE_LOST = wx.PyEventBinder( wxEVT_MOUSE_CAPTURE_LOST ) + +EVT_LEFT_DOWN = wx.PyEventBinder( wxEVT_LEFT_DOWN ) +EVT_LEFT_UP = wx.PyEventBinder( wxEVT_LEFT_UP ) +EVT_MIDDLE_DOWN = wx.PyEventBinder( wxEVT_MIDDLE_DOWN ) +EVT_MIDDLE_UP = wx.PyEventBinder( wxEVT_MIDDLE_UP ) +EVT_RIGHT_DOWN = wx.PyEventBinder( wxEVT_RIGHT_DOWN ) +EVT_RIGHT_UP = wx.PyEventBinder( wxEVT_RIGHT_UP ) +EVT_MOTION = wx.PyEventBinder( wxEVT_MOTION ) +EVT_LEFT_DCLICK = wx.PyEventBinder( wxEVT_LEFT_DCLICK ) +EVT_MIDDLE_DCLICK = wx.PyEventBinder( wxEVT_MIDDLE_DCLICK ) +EVT_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_RIGHT_DCLICK ) +EVT_LEAVE_WINDOW = wx.PyEventBinder( wxEVT_LEAVE_WINDOW ) +EVT_ENTER_WINDOW = wx.PyEventBinder( wxEVT_ENTER_WINDOW ) +EVT_MOUSEWHEEL = wx.PyEventBinder( wxEVT_MOUSEWHEEL ) +EVT_MOUSE_AUX1_DOWN = wx.PyEventBinder( wxEVT_AUX1_DOWN ) +EVT_MOUSE_AUX1_UP = wx.PyEventBinder( wxEVT_AUX1_UP ) +EVT_MOUSE_AUX1_DCLICK = wx.PyEventBinder( wxEVT_AUX1_DCLICK ) +EVT_MOUSE_AUX2_DOWN = wx.PyEventBinder( wxEVT_AUX2_DOWN ) +EVT_MOUSE_AUX2_UP = wx.PyEventBinder( wxEVT_AUX2_UP ) +EVT_MOUSE_AUX2_DCLICK = wx.PyEventBinder( wxEVT_AUX2_DCLICK ) + +EVT_MOUSE_EVENTS = wx.PyEventBinder([ wxEVT_LEFT_DOWN, + wxEVT_LEFT_UP, + wxEVT_MIDDLE_DOWN, + wxEVT_MIDDLE_UP, + wxEVT_RIGHT_DOWN, + wxEVT_RIGHT_UP, + wxEVT_MOTION, + wxEVT_LEFT_DCLICK, + wxEVT_MIDDLE_DCLICK, + wxEVT_RIGHT_DCLICK, + wxEVT_ENTER_WINDOW, + wxEVT_LEAVE_WINDOW, + wxEVT_MOUSEWHEEL, + wxEVT_AUX1_DOWN, + wxEVT_AUX1_UP, + wxEVT_AUX1_DCLICK, + wxEVT_AUX2_DOWN, + wxEVT_AUX2_UP, + wxEVT_AUX2_DCLICK, + ]) + + +# Scrolling from wxWindow (sent to wxScrolledWindow) +EVT_SCROLLWIN = wx.PyEventBinder([ wxEVT_SCROLLWIN_TOP, + wxEVT_SCROLLWIN_BOTTOM, + wxEVT_SCROLLWIN_LINEUP, + wxEVT_SCROLLWIN_LINEDOWN, + wxEVT_SCROLLWIN_PAGEUP, + wxEVT_SCROLLWIN_PAGEDOWN, + wxEVT_SCROLLWIN_THUMBTRACK, + wxEVT_SCROLLWIN_THUMBRELEASE, + ]) + +EVT_SCROLLWIN_TOP = wx.PyEventBinder( wxEVT_SCROLLWIN_TOP ) +EVT_SCROLLWIN_BOTTOM = wx.PyEventBinder( wxEVT_SCROLLWIN_BOTTOM ) +EVT_SCROLLWIN_LINEUP = wx.PyEventBinder( wxEVT_SCROLLWIN_LINEUP ) +EVT_SCROLLWIN_LINEDOWN = wx.PyEventBinder( wxEVT_SCROLLWIN_LINEDOWN ) +EVT_SCROLLWIN_PAGEUP = wx.PyEventBinder( wxEVT_SCROLLWIN_PAGEUP ) +EVT_SCROLLWIN_PAGEDOWN = wx.PyEventBinder( wxEVT_SCROLLWIN_PAGEDOWN ) +EVT_SCROLLWIN_THUMBTRACK = wx.PyEventBinder( wxEVT_SCROLLWIN_THUMBTRACK ) +EVT_SCROLLWIN_THUMBRELEASE = wx.PyEventBinder( wxEVT_SCROLLWIN_THUMBRELEASE ) + +# Scrolling from wx.Slider and wx.ScrollBar +EVT_SCROLL = wx.PyEventBinder([ wxEVT_SCROLL_TOP, + wxEVT_SCROLL_BOTTOM, + wxEVT_SCROLL_LINEUP, + wxEVT_SCROLL_LINEDOWN, + wxEVT_SCROLL_PAGEUP, + wxEVT_SCROLL_PAGEDOWN, + wxEVT_SCROLL_THUMBTRACK, + wxEVT_SCROLL_THUMBRELEASE, + wxEVT_SCROLL_CHANGED, + ]) + +EVT_SCROLL_TOP = wx.PyEventBinder( wxEVT_SCROLL_TOP ) +EVT_SCROLL_BOTTOM = wx.PyEventBinder( wxEVT_SCROLL_BOTTOM ) +EVT_SCROLL_LINEUP = wx.PyEventBinder( wxEVT_SCROLL_LINEUP ) +EVT_SCROLL_LINEDOWN = wx.PyEventBinder( wxEVT_SCROLL_LINEDOWN ) +EVT_SCROLL_PAGEUP = wx.PyEventBinder( wxEVT_SCROLL_PAGEUP ) +EVT_SCROLL_PAGEDOWN = wx.PyEventBinder( wxEVT_SCROLL_PAGEDOWN ) +EVT_SCROLL_THUMBTRACK = wx.PyEventBinder( wxEVT_SCROLL_THUMBTRACK ) +EVT_SCROLL_THUMBRELEASE = wx.PyEventBinder( wxEVT_SCROLL_THUMBRELEASE ) +EVT_SCROLL_CHANGED = wx.PyEventBinder( wxEVT_SCROLL_CHANGED ) +EVT_SCROLL_ENDSCROLL = EVT_SCROLL_CHANGED + +# Scrolling from wx.Slider and wx.ScrollBar, with an id +EVT_COMMAND_SCROLL = wx.PyEventBinder([ wxEVT_SCROLL_TOP, + wxEVT_SCROLL_BOTTOM, + wxEVT_SCROLL_LINEUP, + wxEVT_SCROLL_LINEDOWN, + wxEVT_SCROLL_PAGEUP, + wxEVT_SCROLL_PAGEDOWN, + wxEVT_SCROLL_THUMBTRACK, + wxEVT_SCROLL_THUMBRELEASE, + wxEVT_SCROLL_CHANGED, + ], 1) + +EVT_COMMAND_SCROLL_TOP = wx.PyEventBinder( wxEVT_SCROLL_TOP, 1) +EVT_COMMAND_SCROLL_BOTTOM = wx.PyEventBinder( wxEVT_SCROLL_BOTTOM, 1) +EVT_COMMAND_SCROLL_LINEUP = wx.PyEventBinder( wxEVT_SCROLL_LINEUP, 1) +EVT_COMMAND_SCROLL_LINEDOWN = wx.PyEventBinder( wxEVT_SCROLL_LINEDOWN, 1) +EVT_COMMAND_SCROLL_PAGEUP = wx.PyEventBinder( wxEVT_SCROLL_PAGEUP, 1) +EVT_COMMAND_SCROLL_PAGEDOWN = wx.PyEventBinder( wxEVT_SCROLL_PAGEDOWN, 1) +EVT_COMMAND_SCROLL_THUMBTRACK = wx.PyEventBinder( wxEVT_SCROLL_THUMBTRACK, 1) +EVT_COMMAND_SCROLL_THUMBRELEASE = wx.PyEventBinder( wxEVT_SCROLL_THUMBRELEASE, 1) +EVT_COMMAND_SCROLL_CHANGED = wx.PyEventBinder( wxEVT_SCROLL_CHANGED, 1) +EVT_COMMAND_SCROLL_ENDSCROLL = EVT_COMMAND_SCROLL_CHANGED + +EVT_BUTTON = wx.PyEventBinder( wxEVT_COMMAND_BUTTON_CLICKED, 1) +EVT_CHECKBOX = wx.PyEventBinder( wxEVT_COMMAND_CHECKBOX_CLICKED, 1) +EVT_CHOICE = wx.PyEventBinder( wxEVT_COMMAND_CHOICE_SELECTED, 1) +EVT_LISTBOX = wx.PyEventBinder( wxEVT_COMMAND_LISTBOX_SELECTED, 1) +EVT_LISTBOX_DCLICK = wx.PyEventBinder( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, 1) +EVT_MENU = wx.PyEventBinder( wxEVT_COMMAND_MENU_SELECTED, 1) +EVT_MENU_RANGE = wx.PyEventBinder( wxEVT_COMMAND_MENU_SELECTED, 2) +EVT_SLIDER = wx.PyEventBinder( wxEVT_COMMAND_SLIDER_UPDATED, 1) +EVT_RADIOBOX = wx.PyEventBinder( wxEVT_COMMAND_RADIOBOX_SELECTED, 1) +EVT_RADIOBUTTON = wx.PyEventBinder( wxEVT_COMMAND_RADIOBUTTON_SELECTED, 1) + +EVT_SCROLLBAR = wx.PyEventBinder( wxEVT_COMMAND_SCROLLBAR_UPDATED, 1) +EVT_VLBOX = wx.PyEventBinder( wxEVT_COMMAND_VLBOX_SELECTED, 1) +EVT_COMBOBOX = wx.PyEventBinder( wxEVT_COMMAND_COMBOBOX_SELECTED, 1) +EVT_TOOL = wx.PyEventBinder( wxEVT_COMMAND_TOOL_CLICKED, 1) +EVT_TOOL_RANGE = wx.PyEventBinder( wxEVT_COMMAND_TOOL_CLICKED, 2) +EVT_TOOL_RCLICKED = wx.PyEventBinder( wxEVT_COMMAND_TOOL_RCLICKED, 1) +EVT_TOOL_RCLICKED_RANGE = wx.PyEventBinder( wxEVT_COMMAND_TOOL_RCLICKED, 2) +EVT_TOOL_ENTER = wx.PyEventBinder( wxEVT_COMMAND_TOOL_ENTER, 1) +EVT_TOOL_DROPDOWN = wx.PyEventBinder( wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, 1) +EVT_CHECKLISTBOX = wx.PyEventBinder( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, 1) +EVT_COMBOBOX_DROPDOWN = wx.PyEventBinder( wxEVT_COMMAND_COMBOBOX_DROPDOWN , 1) +EVT_COMBOBOX_CLOSEUP = wx.PyEventBinder( wxEVT_COMMAND_COMBOBOX_CLOSEUP , 1) + +EVT_COMMAND_LEFT_CLICK = wx.PyEventBinder( wxEVT_COMMAND_LEFT_CLICK, 1) +EVT_COMMAND_LEFT_DCLICK = wx.PyEventBinder( wxEVT_COMMAND_LEFT_DCLICK, 1) +EVT_COMMAND_RIGHT_CLICK = wx.PyEventBinder( wxEVT_COMMAND_RIGHT_CLICK, 1) +EVT_COMMAND_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_COMMAND_RIGHT_DCLICK, 1) +EVT_COMMAND_SET_FOCUS = wx.PyEventBinder( wxEVT_COMMAND_SET_FOCUS, 1) +EVT_COMMAND_KILL_FOCUS = wx.PyEventBinder( wxEVT_COMMAND_KILL_FOCUS, 1) +EVT_COMMAND_ENTER = wx.PyEventBinder( wxEVT_COMMAND_ENTER, 1) + +EVT_IDLE = wx.PyEventBinder( wxEVT_IDLE ) + +EVT_UPDATE_UI = wx.PyEventBinder( wxEVT_UPDATE_UI, 1) +EVT_UPDATE_UI_RANGE = wx.PyEventBinder( wxEVT_UPDATE_UI, 2) + +EVT_CONTEXT_MENU = wx.PyEventBinder( wxEVT_CONTEXT_MENU ) + +EVT_TEXT_CUT = wx.PyEventBinder( wxEVT_COMMAND_TEXT_CUT ) +EVT_TEXT_COPY = wx.PyEventBinder( wxEVT_COMMAND_TEXT_COPY ) +EVT_TEXT_PASTE = wx.PyEventBinder( wxEVT_COMMAND_TEXT_PASTE ) + +EVT_THREAD = wx.PyEventBinder( wxEVT_COMMAND_THREAD ) diff --git a/src/wxpy_utils.sip b/src/wxpy_utils.sip index 5b675af2..d199a7da 100644 --- a/src/wxpy_utils.sip +++ b/src/wxpy_utils.sip @@ -62,6 +62,12 @@ inline void wxPyEndBlockThreads(wxPyBlock_t blocked) { PyGILState_Release(blocked); } + +PyObject* wxPyConstructObject(void* ptr, + const wxString& className, + int setThisOwn=0); + + %End @@ -101,4 +107,16 @@ inline void wxPyEndBlockThreads(wxPyBlock_t blocked) { Py_DECREF(uni); // release the temporary Unicode object we created return target; } + + +PyObject* wxPyConstructObject(void* ptr, + const wxString& className, + int setThisOwn) +{ + const sipTypeDef* td = sipFindType(className); + if (!td) + return NULL; + PyObject* transferObj = setThisOwn ? Py_None : NULL; + return sipConvertFromType(ptr, td, transferObj); +} %End diff --git a/unittests/test_app.py b/unittests/test_app.py index d4574d77..02c30bb8 100644 --- a/unittests/test_app.py +++ b/unittests/test_app.py @@ -1,6 +1,7 @@ import unittest2 import wxPhoenix as wx +import warnings #--------------------------------------------------------------------------- @@ -10,12 +11,10 @@ class App(unittest2.TestCase): 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) @@ -23,7 +22,11 @@ class App(unittest2.TestCase): v = wx.version() def test_PySimpleApp(self): - app = wx.PySimpleApp() + # wx.PySimpleApp is supposed to be deprecated, make sure it is. + with warnings.catch_warnings(): + warnings.simplefilter("error") + with self.assertRaises(DeprecationWarning): + app = wx.PySimpleApp() #--------------------------------------------------------------------------- diff --git a/unittests/test_event.py b/unittests/test_event.py index 8d1771c1..d48192ab 100644 --- a/unittests/test_event.py +++ b/unittests/test_event.py @@ -123,6 +123,20 @@ class Events(unittest2.TestCase): evt = wx.WindowDestroyEvent() + def test_eventBinding(self): + class Frame(wx.Frame): + def __init__(self, *args, **kw): + wx.Frame.__init__(self, *args, **kw) + self.Bind(wx.EVT_SIZE, self.onSize) + self.gotEvent = False + def onSize(self, evt): + self.gotEvent = True + evt.EventObject.Close() + app = wx.App() + frm = Frame(None) + frm.Show() + app.MainLoop() + self.assertTrue(frm.gotEvent) #---------------------------------------------------------------------------