From 799d94b50f6bd40b12a8ed4864a658b5af0ee1c2 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 24 Mar 2020 17:36:22 -0700 Subject: [PATCH 01/29] Enable adding extra TypeHeader text in wxListWrapperTemplate --- etgtools/tweaker_tools.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/etgtools/tweaker_tools.py b/etgtools/tweaker_tools.py index 0235438b..e4aefe26 100644 --- a/etgtools/tweaker_tools.py +++ b/etgtools/tweaker_tools.py @@ -865,7 +865,8 @@ def convertFourDoublesTemplate(CLASS): def wxListWrapperTemplate(ListClass, ItemClass, module, RealItemClass=None, - includeConvertToType=False, fakeListClassName=None): + includeConvertToType=False, fakeListClassName=None, + header_extra=''): if RealItemClass is None: RealItemClass = ItemClass @@ -887,6 +888,7 @@ class {ListClass}_iterator /Abstract/ {{ // the C++ implementation of this class %TypeHeaderCode + {header_extra} {TypeDef} class {ListClass}_iterator {{ public: @@ -920,6 +922,7 @@ public: class {ListClass} {{ %TypeHeaderCode + {header_extra} {TypeDef} %End public: From 24be75d44ab70d4dcc73994c616465e67c1bedb7 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 24 Mar 2020 17:37:17 -0700 Subject: [PATCH 02/29] Add --disable-nativeanimation to configure command --- buildtools/build_wxwidgets.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/buildtools/build_wxwidgets.py b/buildtools/build_wxwidgets.py index 2a1c2f55..2c7e9e76 100644 --- a/buildtools/build_wxwidgets.py +++ b/buildtools/build_wxwidgets.py @@ -289,6 +289,7 @@ def main(wxDir, args): "--disable-debugreport", "--enable-uiactionsim", "--enable-autoidman", + "--disable-nativeanimation", ] if sys.platform.startswith("darwin"): @@ -405,6 +406,7 @@ def main(wxDir, args): flags["wxUSE_IFF"] = "1" flags["wxUSE_ACCESSIBILITY"] = "1" flags["wxUSE_WINRT"] = "0" + flags["wxUSE_NATIVE_ANIMATIONCTRL"] = "0" # Remove this when Windows XP finally dies, or when there is a # solution for ticket #13116... From 73b18b66501a90fe41a5781eaae5b71a4b46a777 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 24 Mar 2020 17:37:44 -0700 Subject: [PATCH 03/29] Add animation decoders --- docs/sphinx/itemToModuleMap.json | 8 ++++++++ etg/animate.py | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/sphinx/itemToModuleMap.json b/docs/sphinx/itemToModuleMap.json index fe64cddf..e4481a5d 100644 --- a/docs/sphinx/itemToModuleMap.json +++ b/docs/sphinx/itemToModuleMap.json @@ -110,10 +110,15 @@ "AND":"wx.", "AND_INVERT":"wx.", "AND_REVERSE":"wx.", +"ANIDecoder":"wx.adv.", "ANIMATION_TYPE_ANI":"wx.adv.", "ANIMATION_TYPE_ANY":"wx.adv.", "ANIMATION_TYPE_GIF":"wx.adv.", "ANIMATION_TYPE_INVALID":"wx.adv.", +"ANIM_DONOTREMOVE":"wx.adv.", +"ANIM_TOBACKGROUND":"wx.adv.", +"ANIM_TOPREVIOUS":"wx.adv.", +"ANIM_UNSPECIFIED":"wx.adv.", "ANTIALIAS_DEFAULT":"wx.", "ANTIALIAS_NONE":"wx.", "APPLY":"wx.", @@ -302,6 +307,8 @@ "Animation":"wx.adv.", "AnimationCtrl":"wx.adv.", "AnimationCtrlNameStr":"wx.adv.", +"AnimationDecoder":"wx.adv.", +"AnimationDisposal":"wx.adv.", "AnimationType":"wx.adv.", "AntialiasMode":"wx.", "AnyButton":"wx.", @@ -1306,6 +1313,7 @@ "GBSpan":"wx.", "GCDC":"wx.", "GDIObject":"wx.", +"GIFDecoder":"wx.adv.", "GIFHandler":"wx.", "GLAttribsBase":"wx.glcanvas.", "GLAttributes":"wx.glcanvas.", diff --git a/etg/animate.py b/etg/animate.py index 7bbcd2b1..0a935459 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -19,6 +19,9 @@ DOCSTRING = "" # this script. ITEMS = [ "wxAnimation", "wxAnimationCtrl", + "wxAnimationDecoder", + "wxANIDecoder", + "wxGIFDecoder", ] #--------------------------------------------------------------------------- @@ -45,8 +48,18 @@ def run(): module.insertItemBefore(c, item) - # TODO: It would be nice to be able to use the generic verison on all - # platforms since the native GTK version has some limitations... + #----------------------------------------------------------------- + c = module.find('wxAnimationDecoder') + c.find('DoCanRead').ignore(False) + + c = module.find('wxANIDecoder') + c.find('DoCanRead').ignore(False) + + c = module.find('wxGIFDecoder') + c.find('DoCanRead').ignore(False) + + module.addItem(tools.wxListWrapperTemplate('wxAnimationDecoderList', 'wxAnimationDecoder', module, + header_extra='#include ')) #----------------------------------------------------------------- tools.doCommonTweaks(module) From 3298d643ad818e3a146f3ea61a3af877238999be Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 24 Mar 2020 17:39:35 -0700 Subject: [PATCH 04/29] Update wxWidgets ref --- ext/wxWidgets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/wxWidgets b/ext/wxWidgets index 501e55f9..357f7929 160000 --- a/ext/wxWidgets +++ b/ext/wxWidgets @@ -1 +1 @@ -Subproject commit 501e55f949725fd47bc14ddd7e7e059d376d387c +Subproject commit 357f792971a5f77438bb64115a31185878bb6fe4 From a263e026393eaf1746e15817a55f63000ca7ae39 Mon Sep 17 00:00:00 2001 From: Robin Dunn <> Date: Tue, 24 Mar 2020 18:39:20 -0700 Subject: [PATCH 05/29] Some additional default typeVal items for the stubs generator --- etgtools/tweaker_tools.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/etgtools/tweaker_tools.py b/etgtools/tweaker_tools.py index e4aefe26..3025b64c 100644 --- a/etgtools/tweaker_tools.py +++ b/etgtools/tweaker_tools.py @@ -1334,6 +1334,8 @@ def generateStubs(cppFlag, module, excludes=[], typeValMap={}, typeValMap = copy.copy(typeValMap) typeValMap.update({ 'int': '0', + 'long': '0', + 'unsigned int': '0', 'bool': 'false', 'double': '0.0', 'wxString': 'wxEmptyString', @@ -1342,6 +1344,11 @@ def generateStubs(cppFlag, module, excludes=[], typeValMap={}, 'wxSize': 'wxDefaultSize', 'wxPoint': 'wxDefaultPosition', 'wxFileOffset': '0', + 'wxColour': 'wxNullColour', + 'wxBitmap': 'wxNullBitmap', + 'wxBitmap &': 'wxNullBitmap', + 'wxImage': 'wxNullImage', + 'wxVisualAttributes': 'wxVisualAttributes()', }) code = _StubCodeHolder(cppFlag) @@ -1443,6 +1450,7 @@ def _generateClassStub(code, klass, typeValMap): for item in klass: dispatchMap = { extractors.MethodDef : _generateMethodStub, + extractors.WigCode : lambda c, i, t: None, # ignore this type } func = dispatchMap.get(type(item), None) if func is None: @@ -1456,6 +1464,8 @@ def _generateClassStub(code, klass, typeValMap): def _generateMethodStub(code, method, typeValMap): assert isinstance(method, extractors.MethodDef) + if method.ignored: + return decl = ' ' if method.isVirtual: decl += 'virtual ' From eafc9a3c0985e9134fe6516c5c77c4f056f2c2e3 Mon Sep 17 00:00:00 2001 From: Robin Dunn <> Date: Tue, 24 Mar 2020 18:44:03 -0700 Subject: [PATCH 06/29] Add TODO for handling when the native ctrl is configured --- etg/animate.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/etg/animate.py b/etg/animate.py index 0a935459..a93b784e 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -35,9 +35,24 @@ def run(): # Tweak the parsed meta objects in the module object as needed for # customizing the generated code and docstrings. + # TODO: We'll need a different way to handle things when the native version + # is configured. The stubs generator expects that it is an all or nothing + # situaton, but that is not the case for wxAnimation and wxAnimationCtrl... + + # module.addHeaderCode('#include ') + # tools.generateStubs('wxUSE_GENERIC_ANIMATIONCTRL', module, + # typeValMap={'wxAnimation': 'wxNullAnimation', + # 'wxAnimationDisposal': 'wxANIM_UNSPECIFIED', + # 'wxAnimationType': 'wxANIMATION_TYPE_INVALID', + # },) + c = module.find('wxAnimation') assert isinstance(c, etgtools.ClassDef) + #c.find('GetHandlers').ignore() + module.addItem(tools.wxListWrapperTemplate('wxAnimationDecoderList', 'wxAnimationDecoder', module, + header_extra='#include ')) + c = module.find('wxAnimationCtrl') tools.fixWindowClass(c) module.addGlobalStr('wxAnimationCtrlNameStr', c) @@ -58,8 +73,6 @@ def run(): c = module.find('wxGIFDecoder') c.find('DoCanRead').ignore(False) - module.addItem(tools.wxListWrapperTemplate('wxAnimationDecoderList', 'wxAnimationDecoder', module, - header_extra='#include ')) #----------------------------------------------------------------- tools.doCommonTweaks(module) From 62ab56e6e27696c0e713d94247611e35d2e09bcf Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 25 Mar 2020 16:31:21 -0700 Subject: [PATCH 07/29] --disable-nativeanimation is gone, wxGenericAnimationCtrl is a real class --- buildtools/build_wxwidgets.py | 2 -- docs/sphinx/itemToModuleMap.json | 2 ++ etg/animate.py | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/buildtools/build_wxwidgets.py b/buildtools/build_wxwidgets.py index 2c7e9e76..2a1c2f55 100644 --- a/buildtools/build_wxwidgets.py +++ b/buildtools/build_wxwidgets.py @@ -289,7 +289,6 @@ def main(wxDir, args): "--disable-debugreport", "--enable-uiactionsim", "--enable-autoidman", - "--disable-nativeanimation", ] if sys.platform.startswith("darwin"): @@ -406,7 +405,6 @@ def main(wxDir, args): flags["wxUSE_IFF"] = "1" flags["wxUSE_ACCESSIBILITY"] = "1" flags["wxUSE_WINRT"] = "0" - flags["wxUSE_NATIVE_ANIMATIONCTRL"] = "0" # Remove this when Windows XP finally dies, or when there is a # solution for ticket #13116... diff --git a/docs/sphinx/itemToModuleMap.json b/docs/sphinx/itemToModuleMap.json index e4481a5d..6bd09065 100644 --- a/docs/sphinx/itemToModuleMap.json +++ b/docs/sphinx/itemToModuleMap.json @@ -306,6 +306,7 @@ "AlphaPixelData_Accessor":"wx.", "Animation":"wx.adv.", "AnimationCtrl":"wx.adv.", +"AnimationCtrlGeneric":"wx.adv.", "AnimationCtrlNameStr":"wx.adv.", "AnimationDecoder":"wx.adv.", "AnimationDisposal":"wx.adv.", @@ -1355,6 +1356,7 @@ "Gauge":"wx.", "GaugeNameStr":"wx.", "GenericAboutBox":"wx.adv.", +"GenericAnimationCtrl":"wx.adv.", "GenericCalendarCtrl":"wx.adv.", "GenericDatePickerCtrl":"wx.adv.", "GenericDirCtrl":"wx.", diff --git a/etg/animate.py b/etg/animate.py index a93b784e..697bf304 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -53,10 +53,15 @@ def run(): module.addItem(tools.wxListWrapperTemplate('wxAnimationDecoderList', 'wxAnimationDecoder', module, header_extra='#include ')) + c = module.find('wxAnimationCtrl') tools.fixWindowClass(c) module.addGlobalStr('wxAnimationCtrlNameStr', c) + # Add the generic class too + gen = tools.copyClassDef(c, 'wxGenericAnimationCtrl') + module.insertItemAfter(c, gen) + # move this before wxAnimationCtrl so it can be used for default arg values item = module.find('wxNullAnimation') module.items.remove(item) From 93f75b087c40ba1ec4b480bc41ef5a22a636b379 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 25 Mar 2020 16:32:38 -0700 Subject: [PATCH 08/29] Remove TODO --- etg/animate.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/etg/animate.py b/etg/animate.py index 697bf304..21852d0f 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -35,17 +35,6 @@ def run(): # Tweak the parsed meta objects in the module object as needed for # customizing the generated code and docstrings. - # TODO: We'll need a different way to handle things when the native version - # is configured. The stubs generator expects that it is an all or nothing - # situaton, but that is not the case for wxAnimation and wxAnimationCtrl... - - # module.addHeaderCode('#include ') - # tools.generateStubs('wxUSE_GENERIC_ANIMATIONCTRL', module, - # typeValMap={'wxAnimation': 'wxNullAnimation', - # 'wxAnimationDisposal': 'wxANIM_UNSPECIFIED', - # 'wxAnimationType': 'wxANIMATION_TYPE_INVALID', - # },) - c = module.find('wxAnimation') assert isinstance(c, etgtools.ClassDef) From 192577ec5a51b81e663187ddfab29fa0a1a96b69 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 30 Mar 2020 15:47:01 -0700 Subject: [PATCH 09/29] Add new animation classes --- docs/sphinx/itemToModuleMap.json | 3 +++ etg/animate.py | 25 ++++++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/docs/sphinx/itemToModuleMap.json b/docs/sphinx/itemToModuleMap.json index 6bd09065..f7579478 100644 --- a/docs/sphinx/itemToModuleMap.json +++ b/docs/sphinx/itemToModuleMap.json @@ -305,6 +305,7 @@ "AlphaPixelData":"wx.", "AlphaPixelData_Accessor":"wx.", "Animation":"wx.adv.", +"AnimationBase":"wx.adv.", "AnimationCtrl":"wx.adv.", "AnimationCtrlGeneric":"wx.adv.", "AnimationCtrlNameStr":"wx.adv.", @@ -1356,6 +1357,7 @@ "Gauge":"wx.", "GaugeNameStr":"wx.", "GenericAboutBox":"wx.adv.", +"GenericAnimation":"wx.adv.", "GenericAnimationCtrl":"wx.adv.", "GenericCalendarCtrl":"wx.adv.", "GenericDatePickerCtrl":"wx.adv.", @@ -2530,6 +2532,7 @@ "NullColour":"wx.", "NullCursor":"wx.", "NullFont":"wx.", +"NullGenericAnimation":"wx.adv.", "NullGraphicsBitmap":"wx.", "NullGraphicsBrush":"wx.", "NullGraphicsFont":"wx.", diff --git a/etg/animate.py b/etg/animate.py index 21852d0f..894ca9dd 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -17,7 +17,10 @@ DOCSTRING = "" # The classes and/or the basename of the Doxygen XML files to be processed by # this script. -ITEMS = [ "wxAnimation", +ITEMS = [ "wxAnimationBase", + "wxGenericAnimation", + "wxGenericAnimationCtrl", + "wxAnimation", "wxAnimationCtrl", "wxAnimationDecoder", "wxANIDecoder", @@ -35,29 +38,29 @@ def run(): # Tweak the parsed meta objects in the module object as needed for # customizing the generated code and docstrings. - c = module.find('wxAnimation') - assert isinstance(c, etgtools.ClassDef) - - #c.find('GetHandlers').ignore() - module.addItem(tools.wxListWrapperTemplate('wxAnimationDecoderList', 'wxAnimationDecoder', module, - header_extra='#include ')) - + c = module.find('wxGenericAnimationCtrl') + tools.fixWindowClass(c) c = module.find('wxAnimationCtrl') tools.fixWindowClass(c) + module.addGlobalStr('wxAnimationCtrlNameStr', c) - # Add the generic class too - gen = tools.copyClassDef(c, 'wxGenericAnimationCtrl') - module.insertItemAfter(c, gen) # move this before wxAnimationCtrl so it can be used for default arg values item = module.find('wxNullAnimation') module.items.remove(item) module.insertItemBefore(c, item) + item = module.find('wxNullGenericAnimation') + module.items.remove(item) + module.insertItemBefore(c, item) + #----------------------------------------------------------------- + module.addItem(tools.wxListWrapperTemplate('wxAnimationDecoderList', 'wxAnimationDecoder', module, + header_extra='#include ')) + c = module.find('wxAnimationDecoder') c.find('DoCanRead').ignore(False) From b92bf6388499658d3c249b2306c69ad11ccdec72 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 30 Mar 2020 15:47:24 -0700 Subject: [PATCH 10/29] Add ability to select native of generic animation classes --- demo/AnimateCtrl.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/demo/AnimateCtrl.py b/demo/AnimateCtrl.py index c2a3cd63..c579bb78 100644 --- a/demo/AnimateCtrl.py +++ b/demo/AnimateCtrl.py @@ -1,7 +1,15 @@ #!/usr/bin/env python import wx -from wx.adv import Animation, AnimationCtrl + +if True: + # use the native classes, if the platform has a native widget + from wx.adv import Animation, AnimationCtrl +else: + # Otherwise, force use of the generic widgets on all platforms + from wx.adv import GenericAnimation as Animation + from wx.adv import GenericAnimationCtrl as AnimationCtrl + from Main import opj GIFNames = [ From 58d6eae6d3822527ee65e109cd08569d467519c1 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 30 Mar 2020 15:48:01 -0700 Subject: [PATCH 11/29] Update wxWidgets ref --- ext/wxWidgets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/wxWidgets b/ext/wxWidgets index 357f7929..e72793ab 160000 --- a/ext/wxWidgets +++ b/ext/wxWidgets @@ -1 +1 @@ -Subproject commit 357f792971a5f77438bb64115a31185878bb6fe4 +Subproject commit e72793abec89751594e12402ed375bb6afda3e79 From 089097654dca97894e7d699fd990763125177471 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 30 Mar 2020 16:05:37 -0700 Subject: [PATCH 12/29] Add changelog entry --- CHANGES.rst | 4 ++++ demo/AnimateCtrl.py | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f2c43d01..2b4f7fb4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -88,6 +88,10 @@ New and improved in this release: * Added wx.msw.CHMHelpController, and also a wx.HelpController factory function that creates an instance of the best Help Controller for the platform. (#1536) +* Added wx.GenericAnimation and wx.GenericAnimationCtrl so the generic version + of the animation classes can be used even on the platforms that have a native + version. (#1579) + diff --git a/demo/AnimateCtrl.py b/demo/AnimateCtrl.py index c579bb78..438f933d 100644 --- a/demo/AnimateCtrl.py +++ b/demo/AnimateCtrl.py @@ -2,9 +2,10 @@ import wx -if True: +if False: # use the native classes, if the platform has a native widget - from wx.adv import Animation, AnimationCtrl + from wx.adv import Animation + from wx.adv import AnimationCtrl else: # Otherwise, force use of the generic widgets on all platforms from wx.adv import GenericAnimation as Animation From df018ac7dd8995744b310f3e10496f3ce6453ba0 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 1 Apr 2020 15:29:17 -0700 Subject: [PATCH 13/29] Update wxWidgets ref --- ext/wxWidgets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/wxWidgets b/ext/wxWidgets index e72793ab..6039be52 160000 --- a/ext/wxWidgets +++ b/ext/wxWidgets @@ -1 +1 @@ -Subproject commit e72793abec89751594e12402ed375bb6afda3e79 +Subproject commit 6039be5291caa5319b892f7a7072618e7bbceb51 From 7aac38dbcb507ec7e32f31573384b8b0f273de1f Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 1 Apr 2020 15:30:27 -0700 Subject: [PATCH 14/29] Updates needed for animation updates in wxWidgets --- demo/AnimateCtrl.py | 28 +++++-- docs/sphinx/itemToModuleMap.json | 5 ++ etg/animate.py | 13 ++-- wx/svg/_nanosvg.c | 126 ++++++++++++++++++++++++++----- 4 files changed, 138 insertions(+), 34 deletions(-) diff --git a/demo/AnimateCtrl.py b/demo/AnimateCtrl.py index 438f933d..f78a8485 100644 --- a/demo/AnimateCtrl.py +++ b/demo/AnimateCtrl.py @@ -1,15 +1,18 @@ #!/usr/bin/env python import wx +from wx.adv import Animation -if False: - # use the native classes, if the platform has a native widget - from wx.adv import Animation +UseNative = True +if UseNative: + # Use the native classes, if the platform has a native widget. It will fall + # back to the generic version if there isn't a native one available. from wx.adv import AnimationCtrl + implType = wx.adv.ANIMATION_IMPL_TYPE_NATIVE else: - # Otherwise, force use of the generic widgets on all platforms - from wx.adv import GenericAnimation as Animation + # Or we can force use of the generic widget on all platforms from wx.adv import GenericAnimationCtrl as AnimationCtrl + implType = wx.adv.ANIMATION_IMPL_TYPE_GENERIC from Main import opj @@ -31,16 +34,28 @@ class TestPanel(wx.Panel): sizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) for name in GIFNames: - ani = Animation(opj(name)) + ani = Animation(opj(name), implType=implType) ctrl = AnimationCtrl(self, -1, ani) ctrl.SetBackgroundColour(self.GetBackgroundColour()) ctrl.Play() sizer.Add(ctrl, 0, wx.ALL, 10) + if UseNative and 'wxGTK' in wx.PlatformInfo: + wx.CallAfter(self.updateBestSizes) + border = wx.BoxSizer() border.Add(sizer, 1, wx.EXPAND | wx.ALL, 20) self.SetSizer(border) + def updateBestSizes(self): + # The native control on GTK is not able to set the BestSize of the + # animation widget until after it has finished loading the animation + # images. So here we will invalidate the initial best size, so it will + # be recalculated on the next layout of the sizer. + for child in self.GetChildren(): + if isinstance(child, AnimationCtrl): + child.InvalidateBestSize() + self.Layout() #---------------------------------------------------------------------- @@ -62,7 +77,6 @@ display an animation by extracting frames from a multi-image GIF file. """ - if __name__ == '__main__': import sys,os import run diff --git a/docs/sphinx/itemToModuleMap.json b/docs/sphinx/itemToModuleMap.json index f7579478..fbfdbdcb 100644 --- a/docs/sphinx/itemToModuleMap.json +++ b/docs/sphinx/itemToModuleMap.json @@ -111,6 +111,8 @@ "AND_INVERT":"wx.", "AND_REVERSE":"wx.", "ANIDecoder":"wx.adv.", +"ANIMATION_IMPL_TYPE_GENERIC":"wx.adv.", +"ANIMATION_IMPL_TYPE_NATIVE":"wx.adv.", "ANIMATION_TYPE_ANI":"wx.adv.", "ANIMATION_TYPE_ANY":"wx.adv.", "ANIMATION_TYPE_GIF":"wx.adv.", @@ -311,6 +313,9 @@ "AnimationCtrlNameStr":"wx.adv.", "AnimationDecoder":"wx.adv.", "AnimationDisposal":"wx.adv.", +"AnimationGenericImpl":"wx.adv.", +"AnimationImpl":"wx.adv.", +"AnimationImplType":"wx.adv.", "AnimationType":"wx.adv.", "AntialiasMode":"wx.", "AnyButton":"wx.", diff --git a/etg/animate.py b/etg/animate.py index 894ca9dd..cde5ad9a 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -17,10 +17,10 @@ DOCSTRING = "" # The classes and/or the basename of the Doxygen XML files to be processed by # this script. -ITEMS = [ "wxAnimationBase", - "wxGenericAnimation", - "wxGenericAnimationCtrl", +ITEMS = [ "wxAnimationImpl", + "wxAnimationGenericImpl", "wxAnimation", + "wxGenericAnimationCtrl", "wxAnimationCtrl", "wxAnimationDecoder", "wxANIDecoder", @@ -47,15 +47,14 @@ def run(): module.addGlobalStr('wxAnimationCtrlNameStr', c) + c = module.find('wxAnimationImpl') + c.addPrivateCopyCtor() + # move this before wxAnimationCtrl so it can be used for default arg values item = module.find('wxNullAnimation') module.items.remove(item) module.insertItemBefore(c, item) - item = module.find('wxNullGenericAnimation') - module.items.remove(item) - module.insertItemBefore(c, item) - #----------------------------------------------------------------- module.addItem(tools.wxListWrapperTemplate('wxAnimationDecoderList', 'wxAnimationDecoder', module, diff --git a/wx/svg/_nanosvg.c b/wx/svg/_nanosvg.c index 5139fbe4..cdba2718 100644 --- a/wx/svg/_nanosvg.c +++ b/wx/svg/_nanosvg.c @@ -1,4 +1,4 @@ -/* Generated by Cython 0.29.13 */ +/* Generated by Cython 0.29.15 */ /* BEGIN: Cython Metadata { @@ -40,8 +40,8 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) #error Cython requires Python 2.6+ or Python 3.3+. #else -#define CYTHON_ABI "0_29_13" -#define CYTHON_HEX_VERSION 0x001D0DF0 +#define CYTHON_ABI "0_29_15" +#define CYTHON_HEX_VERSION 0x001D0FF0 #define CYTHON_FUTURE_DIVISION 0 #include #ifndef offsetof @@ -12186,7 +12186,12 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGimageBase = { sizeof(struct __pyx_obj_2wx_3svg_8_nanosvg_SVGimageBase), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_2wx_3svg_8_nanosvg_SVGimageBase, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -12239,6 +12244,9 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGimageBase = { #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static struct __pyx_vtabstruct_2wx_3svg_8_nanosvg_SVGshape __pyx_vtable_2wx_3svg_8_nanosvg_SVGshape; @@ -12376,7 +12384,12 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGshape = { sizeof(struct __pyx_obj_2wx_3svg_8_nanosvg_SVGshape), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_2wx_3svg_8_nanosvg_SVGshape, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -12429,6 +12442,9 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGshape = { #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static struct __pyx_vtabstruct_2wx_3svg_8_nanosvg_SVGpath __pyx_vtable_2wx_3svg_8_nanosvg_SVGpath; @@ -12521,7 +12537,12 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGpath = { sizeof(struct __pyx_obj_2wx_3svg_8_nanosvg_SVGpath), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_2wx_3svg_8_nanosvg_SVGpath, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -12574,6 +12595,9 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGpath = { #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static struct __pyx_vtabstruct_2wx_3svg_8_nanosvg_SVGpaint __pyx_vtable_2wx_3svg_8_nanosvg_SVGpaint; @@ -12641,7 +12665,12 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGpaint = { sizeof(struct __pyx_obj_2wx_3svg_8_nanosvg_SVGpaint), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_2wx_3svg_8_nanosvg_SVGpaint, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -12694,6 +12723,9 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGpaint = { #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static struct __pyx_vtabstruct_2wx_3svg_8_nanosvg_SVGgradient __pyx_vtable_2wx_3svg_8_nanosvg_SVGgradient; @@ -12766,7 +12798,12 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGgradient = { sizeof(struct __pyx_obj_2wx_3svg_8_nanosvg_SVGgradient), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_2wx_3svg_8_nanosvg_SVGgradient, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -12819,6 +12856,9 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGgradient = { #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static struct __pyx_vtabstruct_2wx_3svg_8_nanosvg_SVGgradientStop __pyx_vtable_2wx_3svg_8_nanosvg_SVGgradientStop; @@ -12881,7 +12921,12 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGgradientStop = { sizeof(struct __pyx_obj_2wx_3svg_8_nanosvg_SVGgradientStop), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_2wx_3svg_8_nanosvg_SVGgradientStop, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -12934,6 +12979,9 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg_SVGgradientStop = { #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static struct __pyx_obj_2wx_3svg_8_nanosvg___pyx_scope_struct____get__ *__pyx_freelist_2wx_3svg_8_nanosvg___pyx_scope_struct____get__[8]; @@ -12979,7 +13027,12 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg___pyx_scope_struct____get__ = sizeof(struct __pyx_obj_2wx_3svg_8_nanosvg___pyx_scope_struct____get__), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_2wx_3svg_8_nanosvg___pyx_scope_struct____get__, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -13032,6 +13085,9 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg___pyx_scope_struct____get__ = #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static struct __pyx_obj_2wx_3svg_8_nanosvg___pyx_scope_struct_1___get__ *__pyx_freelist_2wx_3svg_8_nanosvg___pyx_scope_struct_1___get__[8]; @@ -13077,7 +13133,12 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg___pyx_scope_struct_1___get__ = sizeof(struct __pyx_obj_2wx_3svg_8_nanosvg___pyx_scope_struct_1___get__), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_2wx_3svg_8_nanosvg___pyx_scope_struct_1___get__, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -13130,6 +13191,9 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg___pyx_scope_struct_1___get__ = #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static struct __pyx_obj_2wx_3svg_8_nanosvg___pyx_scope_struct_2___get__ *__pyx_freelist_2wx_3svg_8_nanosvg___pyx_scope_struct_2___get__[8]; @@ -13175,7 +13239,12 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg___pyx_scope_struct_2___get__ = sizeof(struct __pyx_obj_2wx_3svg_8_nanosvg___pyx_scope_struct_2___get__), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_2wx_3svg_8_nanosvg___pyx_scope_struct_2___get__, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -13228,6 +13297,9 @@ static PyTypeObject __pyx_type_2wx_3svg_8_nanosvg___pyx_scope_struct_2___get__ = #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static PyObject *__pyx_tp_new___Pyx_EnumMeta(PyTypeObject *t, PyObject *a, PyObject *k) { @@ -13296,7 +13368,12 @@ static PyTypeObject __Pyx_EnumMeta = { sizeof(struct __pyx_obj___Pyx_EnumMeta), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc___Pyx_EnumMeta, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 @@ -13349,6 +13426,9 @@ static PyTypeObject __Pyx_EnumMeta = { #if PY_VERSION_HEX >= 0x030800b1 0, /*tp_vectorcall*/ #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif }; static PyMethodDef __pyx_methods[] = { @@ -17773,43 +17853,43 @@ static int __Pyx_setup_reduce(PyObject* type_obj) { PyObject *setstate = NULL; PyObject *setstate_cython = NULL; #if CYTHON_USE_PYTYPE_LOOKUP - if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto GOOD; + if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; #else - if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto GOOD; + if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; #endif #if CYTHON_USE_PYTYPE_LOOKUP - object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto BAD; + object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; #else - object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto BAD; + object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; #endif - reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto BAD; + reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; if (reduce_ex == object_reduce_ex) { #if CYTHON_USE_PYTYPE_LOOKUP - object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto BAD; + object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; #else - object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto BAD; + object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; #endif - reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto BAD; + reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { - reduce_cython = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_cython); if (unlikely(!reduce_cython)) goto BAD; - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto BAD; + reduce_cython = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_cython); if (unlikely(!reduce_cython)) goto __PYX_BAD; + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); if (!setstate) PyErr_Clear(); if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { - setstate_cython = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate_cython); if (unlikely(!setstate_cython)) goto BAD; - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto BAD; + setstate_cython = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate_cython); if (unlikely(!setstate_cython)) goto __PYX_BAD; + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; } PyType_Modified((PyTypeObject*)type_obj); } } - goto GOOD; -BAD: + goto __PYX_GOOD; +__PYX_BAD: if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); ret = -1; -GOOD: +__PYX_GOOD: #if !CYTHON_USE_PYTYPE_LOOKUP Py_XDECREF(object_reduce); Py_XDECREF(object_reduce_ex); @@ -18599,6 +18679,9 @@ static PyTypeObject __pyx_CyFunctionType_type = { #if PY_VERSION_HEX >= 0x030800b1 0, #endif +#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, +#endif }; static int __pyx_CyFunction_init(void) { __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); @@ -21104,6 +21187,9 @@ static PyTypeObject __pyx_GeneratorType_type = { #if PY_VERSION_HEX >= 0x030800b1 0, #endif +#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, +#endif }; static int __pyx_Generator_init(void) { __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; From 669b11d49751b6e0b32d6e39ba67eac5d3ce340d Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Thu, 2 Apr 2020 16:32:44 -0700 Subject: [PATCH 15/29] Update wxWidgets ref --- ext/wxWidgets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/wxWidgets b/ext/wxWidgets index 6039be52..af4ca011 160000 --- a/ext/wxWidgets +++ b/ext/wxWidgets @@ -1 +1 @@ -Subproject commit 6039be5291caa5319b892f7a7072618e7bbceb51 +Subproject commit af4ca011482da5ae682a74e5ee639793cee92ba8 From 75d8def97c50ca15945f6382276c8392d8c6d314 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Thu, 2 Apr 2020 16:32:59 -0700 Subject: [PATCH 16/29] Trim whitespace --- CHANGES.rst | 53 ++++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 2b4f7fb4..bd90e676 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -18,7 +18,7 @@ Pip: ``pip install wxPython==4.1.0`` Starting with this release wxPython has switched to tracking the wxWidgets master branch (version 3.1.x) for the wxWidgets source code, which wxPython is -built upon, and which is included in the wxPython source archives. +built upon, and which is included in the wxPython source archives. New and improved in this release: @@ -37,8 +37,8 @@ New and improved in this release: with warnings enabled so you can see which class, method or function calls you need to change. -* Bug fixes in wx.lib.calendar: key navigation across month boundaries is now - possible; key navigation now sets the date and fires the EVT_CALENDAR event; +* Bug fixes in wx.lib.calendar: key navigation across month boundaries is now + possible; key navigation now sets the date and fires the EVT_CALENDAR event; setter APIs now set the date correctly (#1230). * Switch to using a wx.Overlay in the Widget Inspection Tool to highlight @@ -49,7 +49,7 @@ New and improved in this release: * Grafted on a EnableSystemTheme method to the classes which support it. This can be used to disable the default system theme on Windows for native widgets - like wx.ListCtrl, wx.TreeCtrl and wx.dataview.DataViewCtrl. It has no effect + like wx.ListCtrl, wx.TreeCtrl and wx.dataview.DataViewCtrl. It has no effect on the other platforms. * The wx.WS_EX_VALIDATE_RECURSIVELY extended style flag is obsolete, as it is @@ -60,13 +60,13 @@ New and improved in this release: * Fix a sometimes crash when using a wx.Overlay by letting the wx.DCOverlay hold a reference to the DC, to ensure that the DCOverlay is destroyed first. (PR#1301) - + * Replaced the Vagrant VMs used for building wxPython for various Linux distros with Docker images. * Add some missing methods in wx.adv.BitmapComboBox (#1307) -* Added the wx.svg package which contains code for parsing SVG (Scalable Vector +* Added the wx.svg package which contains code for parsing SVG (Scalable Vector Graphics) files, and also code for integrating with wxPython. It can rasterize the SVG to a wx.Bitmap of any size with no loss of quality, and it can also render the SVG directly to a wx.GraphicsContext using the GC's drawing @@ -75,10 +75,10 @@ New and improved in this release: * Ported the embedding sample from Classic, which shows how to use wxPython from a C++ wxWidgets application that embeds Python. (PR #1353) -* Fixed wx.GetApp() to use wxWidgets' global wxApp instance instead of +* Fixed wx.GetApp() to use wxWidgets' global wxApp instance instead of maintaining its own pointer. This way, if the wxApp is created by C++ code wxPython will still be able to get access to it. (#1126) - + * Added wrappers for the wx.ActivityIndicator class. * Added wrappers for the wx.CollapsibleHeaderCtrl class. @@ -88,10 +88,9 @@ New and improved in this release: * Added wx.msw.CHMHelpController, and also a wx.HelpController factory function that creates an instance of the best Help Controller for the platform. (#1536) -* Added wx.GenericAnimation and wx.GenericAnimationCtrl so the generic version - of the animation classes can be used even on the platforms that have a native - version. (#1579) - +* Added wx.GenericAnimationCtrl so the generic version of the animation classes + can be used even on the platforms that have a native version. (#1579) + @@ -134,13 +133,13 @@ Pip: ``pip install wxPython==4.0.7`` This release is comprised mostly of fixes and minor features which have been back-ported from the master branch. This release is likely the last release of the 4.0.x release series, and is certainly the last 4.0.x release that will -support Python 2.7. It may still continue to build for Python 2.7 for some time, +support Python 2.7. It may still continue to build for Python 2.7 for some time, but no extra effort will be expended to keep it compatible. This release provides the following changes: -* Bug fixes in wx.lib.calendar: key navigation across month boundaries is now - possible; key navigation now sets the date and fires the EVT_CALENDAR event; +* Bug fixes in wx.lib.calendar: key navigation across month boundaries is now + possible; key navigation now sets the date and fires the EVT_CALENDAR event; setter APIs now set the date correctly (#1230). * Switch to using a wx.Overlay in the Widget Inspection Tool to highlight @@ -152,16 +151,16 @@ This release provides the following changes: * Fix a sometimes crash when using a wx.Overlay by letting the wx.DCOverlay hold a reference to the DC, to ensure that the DCOverlay is destroyed first. (PR#1301) - + * Ported the embedding sample from Classic, which shows how to use wxPython from a C++ wxWidgets application that embeds Python. (PR #1353) -* Fixed wx.GetApp() to use wxWidgets' global wxApp instance instead of +* Fixed wx.GetApp() to use wxWidgets' global wxApp instance instead of maintaining its own pointer. This way, if the wxApp is created by C++ code wxPython will still be able to get access to it. (#1126) - -* Several other PRs have been backported from the master branch (which will - become wxPython 4.1.0), the full list can be seen here: + +* Several other PRs have been backported from the master branch (which will + become wxPython 4.1.0), the full list can be seen here: https://github.com/wxWidgets/Phoenix/pull/1357 @@ -185,8 +184,8 @@ This release provides the following fixes: * Reverted the change that loads up install_requires from the contents of requirements.txt. Split the requirements.txt file into one for install and one for development. - - + + 4.0.5 "St. Helens Day" @@ -199,21 +198,21 @@ Pip: ``pip install wxPython==4.0.5`` Changes in this release include the following: -* Added missing HtmlWindow.ScrollToAnchor method, and also a couple methods +* Added missing HtmlWindow.ScrollToAnchor method, and also a couple methods in HtmlCell too. (#1141) -* Added missing setters for the wheel-related properties in wx.MouseEvent. +* Added missing setters for the wheel-related properties in wx.MouseEvent. (#1140) -* Updated wxWidgets commit reference, bringing fixes for #1140, #1086 and +* Updated wxWidgets commit reference, bringing fixes for #1140, #1086 and #1147. -* Fix the use of the output parameter in HtmlWindow.OnOpeningURL the same way +* Fix the use of the output parameter in HtmlWindow.OnOpeningURL the same way it was fixed in HtmlWindowInterface.OnHTMLOpeningURL. (#1068) * Fixed a crashing bug when using a member of a transient wx.VisualAttributes object. Also set the attributes to be read-only to simplify the fix. (#1198). - + * Updated the sip being used in wxPython builds to version 4.19.16. * Added helper functions to check results of wxWidgets configure during the From 0af8589dffad0a5d5fecb86ed3ce49e3a976d83f Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Fri, 3 Apr 2020 14:14:12 -0700 Subject: [PATCH 17/29] wxAnimationGenericImpl is not public --- etg/animate.py | 1 - 1 file changed, 1 deletion(-) diff --git a/etg/animate.py b/etg/animate.py index cde5ad9a..d9c77683 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -18,7 +18,6 @@ DOCSTRING = "" # The classes and/or the basename of the Doxygen XML files to be processed by # this script. ITEMS = [ "wxAnimationImpl", - "wxAnimationGenericImpl", "wxAnimation", "wxGenericAnimationCtrl", "wxAnimationCtrl", From 8d998a9d3c61a3cf53d511ac8f049927ba900844 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Fri, 3 Apr 2020 14:15:30 -0700 Subject: [PATCH 18/29] Update wxWidgets ref --- ext/wxWidgets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/wxWidgets b/ext/wxWidgets index af4ca011..ce808580 160000 --- a/ext/wxWidgets +++ b/ext/wxWidgets @@ -1 +1 @@ -Subproject commit af4ca011482da5ae682a74e5ee639793cee92ba8 +Subproject commit ce8085808c46c54c45459b43b2ed7d12a142b834 From 852554144a78870df04456d79d22b0a8f17ac549 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Sun, 5 Apr 2020 18:30:22 -0700 Subject: [PATCH 19/29] Update wxWidgets ref --- ext/wxWidgets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/wxWidgets b/ext/wxWidgets index ce808580..af7890e3 160000 --- a/ext/wxWidgets +++ b/ext/wxWidgets @@ -1 +1 @@ -Subproject commit ce8085808c46c54c45459b43b2ed7d12a142b834 +Subproject commit af7890e330a8a900f8e05616745dc6704db158a0 From 1b579fc64827f86db4748ad4dc303cef74f424e9 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Sun, 5 Apr 2020 18:31:09 -0700 Subject: [PATCH 20/29] More updates for changes in wxWidgets animation classes --- demo/AnimateCtrl.py | 4 +--- etg/animate.py | 18 +++++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/demo/AnimateCtrl.py b/demo/AnimateCtrl.py index f78a8485..fe909c3e 100644 --- a/demo/AnimateCtrl.py +++ b/demo/AnimateCtrl.py @@ -8,11 +8,9 @@ if UseNative: # Use the native classes, if the platform has a native widget. It will fall # back to the generic version if there isn't a native one available. from wx.adv import AnimationCtrl - implType = wx.adv.ANIMATION_IMPL_TYPE_NATIVE else: # Or we can force use of the generic widget on all platforms from wx.adv import GenericAnimationCtrl as AnimationCtrl - implType = wx.adv.ANIMATION_IMPL_TYPE_GENERIC from Main import opj @@ -34,7 +32,7 @@ class TestPanel(wx.Panel): sizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) for name in GIFNames: - ani = Animation(opj(name), implType=implType) + ani = Animation(opj(name)) ctrl = AnimationCtrl(self, -1, ani) ctrl.SetBackgroundColour(self.GetBackgroundColour()) ctrl.Play() diff --git a/etg/animate.py b/etg/animate.py index d9c77683..8eb1a7ef 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -17,10 +17,9 @@ DOCSTRING = "" # The classes and/or the basename of the Doxygen XML files to be processed by # this script. -ITEMS = [ "wxAnimationImpl", - "wxAnimation", - "wxGenericAnimationCtrl", +ITEMS = [ "wxAnimation", "wxAnimationCtrl", + "wxGenericAnimationCtrl", "wxAnimationDecoder", "wxANIDecoder", "wxGIFDecoder", @@ -37,18 +36,19 @@ def run(): # Tweak the parsed meta objects in the module object as needed for # customizing the generated code and docstrings. - c = module.find('wxGenericAnimationCtrl') - tools.fixWindowClass(c) - c = module.find('wxAnimationCtrl') tools.fixWindowClass(c) + play = c.find('Play') + + c = module.find('wxGenericAnimationCtrl') + tools.fixWindowClass(c) + # Insert a copy of the base class Play into this class. It's not in the + # inteface docs, but sip needs to see it there. + c.find('Play').overloads.append(play) module.addGlobalStr('wxAnimationCtrlNameStr', c) - c = module.find('wxAnimationImpl') - c.addPrivateCopyCtor() - # move this before wxAnimationCtrl so it can be used for default arg values item = module.find('wxNullAnimation') module.items.remove(item) From 0d838c12a33aa15a3336999c29a3041453beaf4e Mon Sep 17 00:00:00 2001 From: Robin Dunn <> Date: Mon, 6 Apr 2020 11:53:25 -0700 Subject: [PATCH 21/29] Make wxGenericAnimationCtrl derive from wxControl, and add missing methods to it. --- etg/animate.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/etg/animate.py b/etg/animate.py index 8eb1a7ef..d58c54aa 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -39,13 +39,35 @@ def run(): c = module.find('wxAnimationCtrl') tools.fixWindowClass(c) play = c.find('Play') + others = [ + c.find('Stop'), + c.find('IsPlaying'), + c.find('Load'), + c.find('LoadFile'), + c.find('GetAnimation'), + c.find('SetAnimation'), + c.find('SetInactiveBitmap'), + c.find('GetInactiveBitmap'), + c.find('CreateAnimation'), + ] c = module.find('wxGenericAnimationCtrl') + c.bases = ['wxControl'] + c.addHeaderCode('#include ') tools.fixWindowClass(c) + # Insert a copy of the base class Play into this class. It's not in the - # inteface docs, but sip needs to see it there. + # inteface docs, but sip needs to see it there, since the one that is there + # has a different signature. c.find('Play').overloads.append(play) + # Since we pretend that the base class is wxControl (because there are + # different parents in different builds) then we need to copy in some + # methods it will be inheriting from the real base class, which is not + # public. + for m in others: + c.addItem(m) + module.addGlobalStr('wxAnimationCtrlNameStr', c) From 0d6f2d211efdee1c7eb8b5e500887b26ae03c6e4 Mon Sep 17 00:00:00 2001 From: Robin Dunn <> Date: Mon, 6 Apr 2020 12:02:04 -0700 Subject: [PATCH 22/29] Changes needed to ensure both the native and generic controls can be used in the wxGTK build. --- demo/AnimateCtrl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/AnimateCtrl.py b/demo/AnimateCtrl.py index fe909c3e..336d5d32 100644 --- a/demo/AnimateCtrl.py +++ b/demo/AnimateCtrl.py @@ -32,8 +32,8 @@ class TestPanel(wx.Panel): sizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) for name in GIFNames: - ani = Animation(opj(name)) - ctrl = AnimationCtrl(self, -1, ani) + ctrl = AnimationCtrl(self) + ctrl.LoadFile(opj(name)) ctrl.SetBackgroundColour(self.GetBackgroundColour()) ctrl.Play() sizer.Add(ctrl, 0, wx.ALL, 10) From 4dcd9a7114660d0f86e5cf9e933cd3240c12a9ea Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 6 Apr 2020 12:50:38 -0700 Subject: [PATCH 23/29] Ensure animationctrl virtuals are still virtual in the wrapper classes --- etg/animate.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etg/animate.py b/etg/animate.py index d58c54aa..ee64ba9f 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -39,6 +39,7 @@ def run(): c = module.find('wxAnimationCtrl') tools.fixWindowClass(c) play = c.find('Play') + play.isVirtual = True others = [ c.find('Stop'), c.find('IsPlaying'), @@ -66,6 +67,7 @@ def run(): # methods it will be inheriting from the real base class, which is not # public. for m in others: + m.isVirtual = True c.addItem(m) module.addGlobalStr('wxAnimationCtrlNameStr', c) From 60377791510ffe8d2f6e97335c0c5948baff8900 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 6 Apr 2020 12:52:43 -0700 Subject: [PATCH 24/29] Try different usages of creating the animation and control --- demo/AnimateCtrl.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/demo/AnimateCtrl.py b/demo/AnimateCtrl.py index 336d5d32..f2260263 100644 --- a/demo/AnimateCtrl.py +++ b/demo/AnimateCtrl.py @@ -32,8 +32,15 @@ class TestPanel(wx.Panel): sizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) for name in GIFNames: - ctrl = AnimationCtrl(self) - ctrl.LoadFile(opj(name)) + if False: + ctrl = AnimationCtrl(self) + ani = ctrl.CreateAnimation() + ani.LoadFile(opj(name)) + ctrl.SetAnimation(ani) + else: + ctrl = AnimationCtrl(self) + ctrl.LoadFile(opj(name)) + ctrl.SetBackgroundColour(self.GetBackgroundColour()) ctrl.Play() sizer.Add(ctrl, 0, wx.ALL, 10) From bd6af90b41c65b970d6f9abdfc0b518668c9f63d Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 6 Apr 2020 14:55:45 -0700 Subject: [PATCH 25/29] Add CreateCompatibleAnimation --- demo/AnimateCtrl.py | 19 +++++++++++++++++-- etg/animate.py | 7 +++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/demo/AnimateCtrl.py b/demo/AnimateCtrl.py index f2260263..0b308abf 100644 --- a/demo/AnimateCtrl.py +++ b/demo/AnimateCtrl.py @@ -29,15 +29,29 @@ class TestPanel(wx.Panel): def __init__(self, parent, log): self.log = log wx.Panel.__init__(self, parent, -1) - sizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) + for name in GIFNames: - if False: + # There are a few usage pattens for creating the control and the + # animation object. They're more-or-less equivalent, but if you have + # non-standard needs in your application then one pattern may make + # more sense for you to use. + if True: + # If you need a separate animation object then you can have the + # control create one for you. ctrl = AnimationCtrl(self) ani = ctrl.CreateAnimation() ani.LoadFile(opj(name)) ctrl.SetAnimation(ani) + elif False: + # if you need to have the animation object before the control is + # created, then you can do it like this: + ani = AnimationCtrl.CreateCompatibleAnimation() + ani.LoadFile(opj(name)) + ctrl = AnimationCtrl(self, -1, ani) else: + # Or you can keep it simple and just have the control make and + # use its own animation object internally. ctrl = AnimationCtrl(self) ctrl.LoadFile(opj(name)) @@ -46,6 +60,7 @@ class TestPanel(wx.Panel): sizer.Add(ctrl, 0, wx.ALL, 10) if UseNative and 'wxGTK' in wx.PlatformInfo: + # See comment in updateBestSizes below wx.CallAfter(self.updateBestSizes) border = wx.BoxSizer() diff --git a/etg/animate.py b/etg/animate.py index ee64ba9f..bee5d793 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -38,8 +38,11 @@ def run(): c = module.find('wxAnimationCtrl') tools.fixWindowClass(c) + + # Grab some MethodDefs that need to be copied to wxGenericAnimationCtrl play = c.find('Play') play.isVirtual = True + cca = c.find('CreateCompatibleAnimation') others = [ c.find('Stop'), c.find('IsPlaying'), @@ -70,6 +73,10 @@ def run(): m.isVirtual = True c.addItem(m) + # This one is static, and not virtual, so we'll do it separately + c.addItem(cca) + + module.addGlobalStr('wxAnimationCtrlNameStr', c) From ca1d3679837ce62c542fa0a90d49f5f4c17984d5 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 6 Apr 2020 14:56:04 -0700 Subject: [PATCH 26/29] Update wxWidgets ref --- ext/wxWidgets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/wxWidgets b/ext/wxWidgets index af7890e3..f2ed3a53 160000 --- a/ext/wxWidgets +++ b/ext/wxWidgets @@ -1 +1 @@ -Subproject commit af7890e330a8a900f8e05616745dc6704db158a0 +Subproject commit f2ed3a5376d435d4e6cadd20b78b3685b997555a From 04c82c58053f40297dfd9e1ada9afda5fad9114b Mon Sep 17 00:00:00 2001 From: Robin Dunn <> Date: Mon, 6 Apr 2020 15:07:18 -0700 Subject: [PATCH 27/29] Some of the copied methods are not virtuals --- etg/animate.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/etg/animate.py b/etg/animate.py index bee5d793..bbd32ac3 100644 --- a/etg/animate.py +++ b/etg/animate.py @@ -42,7 +42,6 @@ def run(): # Grab some MethodDefs that need to be copied to wxGenericAnimationCtrl play = c.find('Play') play.isVirtual = True - cca = c.find('CreateCompatibleAnimation') others = [ c.find('Stop'), c.find('IsPlaying'), @@ -53,7 +52,12 @@ def run(): c.find('SetInactiveBitmap'), c.find('GetInactiveBitmap'), c.find('CreateAnimation'), + c.find('CreateCompatibleAnimation'), ] + nonvirtual = [ 'GetAnimation', 'GetInactiveBitmap', 'CreateAnimation', + 'CreateCompatibleAnimation', + ] + c = module.find('wxGenericAnimationCtrl') c.bases = ['wxControl'] @@ -70,11 +74,10 @@ def run(): # methods it will be inheriting from the real base class, which is not # public. for m in others: - m.isVirtual = True + if m.name not in nonvirtual: + m.isVirtual = True c.addItem(m) - # This one is static, and not virtual, so we'll do it separately - c.addItem(cca) module.addGlobalStr('wxAnimationCtrlNameStr', c) From 550cf160342246c72768480c2ed7e32e08f95e93 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 6 Apr 2020 15:12:55 -0700 Subject: [PATCH 28/29] Rename the module in the demo to match the actual class name --- demo/{AnimateCtrl.py => AnimationCtrl.py} | 2 +- demo/demodata.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename demo/{AnimateCtrl.py => AnimationCtrl.py} (99%) diff --git a/demo/AnimateCtrl.py b/demo/AnimationCtrl.py similarity index 99% rename from demo/AnimateCtrl.py rename to demo/AnimationCtrl.py index 0b308abf..72b4c017 100644 --- a/demo/AnimateCtrl.py +++ b/demo/AnimationCtrl.py @@ -36,7 +36,7 @@ class TestPanel(wx.Panel): # animation object. They're more-or-less equivalent, but if you have # non-standard needs in your application then one pattern may make # more sense for you to use. - if True: + if False: # If you need a separate animation object then you can have the # control create one for you. ctrl = AnimationCtrl(self) diff --git a/demo/demodata.py b/demo/demodata.py index 468b3779..e9172620 100644 --- a/demo/demodata.py +++ b/demo/demodata.py @@ -247,7 +247,7 @@ _treeList = [ ('Using Images', [ 'AdjustChannels', 'AlphaDrawing', - 'AnimateCtrl', + 'AnimationCtrl', 'ArtProvider', 'BitmapFromBuffer', 'Cursor', From 2cff46c10a3208ad23eaad1aec089416e99461ad Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 6 Apr 2020 15:44:33 -0700 Subject: [PATCH 29/29] Add more details to the changelog for the animation changes. --- CHANGES.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index bd90e676..e41f6936 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -88,8 +88,11 @@ New and improved in this release: * Added wx.msw.CHMHelpController, and also a wx.HelpController factory function that creates an instance of the best Help Controller for the platform. (#1536) -* Added wx.GenericAnimationCtrl so the generic version of the animation classes - can be used even on the platforms that have a native version. (#1579) +* Added wx.adv.GenericAnimationCtrl so the generic version of the animation classes + can be used even on the platforms that have a native version. Note that due to + internal changes to support both types of animations, some API changes in how + the Animation objects are created. See the AnimationCtrl.py sample in the demo + for the various usage patterns (#1579)