Pair of 2.5.1.5 backwards compatibility items

Not sure how crucial the backwards compatibility portion of the
2.5.1.5 release is but I ran into these two issues when running the first
of some 2.4.2.4 code under 2.5.1.5 (still using the wxPython namespace):

* The "old" wxDC.DrawBitmap method doesn't appear to be one of those that
  maintained the old x,y signature rather than a wxPoint.

* wxSizer.AddMany() now appears to require that for spacers the size
  be a tuple. This is different than 2.4.2.4 and from my perspective
  different than the existing docs for 2.5.1.5 since they show the Add
  for a spacer with just distinct x and y parameters. It looks like
  the problem might be how the wrapper for Add() itself changed. I
  see some special support in the AddMany code (compared to 2.4.2.4)
  to try to handle a simple spacer case, but in my case I have a
  spacer with a proportion argument, so the code ignores that. For
  example, I sometimes have AddMany calls like:

      sizer.AddMany([(0,0,3),
                     (title, 0, wx.wxCENTER, 1),
                     (0,0,1),
                     (hsizer, 0, wx.wxEXPAND),
                     (0,0,1),
                     (go, 0, wx.wxALIGN_CENTER),
                     (msgbox, 6, wx.wxEXPAND|wx.wxALL, 20)])

  Should this still work (based on the docs for wxSizer.Add) or should
  I assume the signature for Add/AddMany should explicitly use a tuple
  for sizes?

Thanks.

-- David

David Bolen wrote:

Not sure how crucial the backwards compatibility portion of the
2.5.1.5 release is

Not very. Although backwards compatibility was always attempted, it took second priority in this release. First priority (other than moving to wxWidgets 2.5 and SWIG 1.3) was cleanup, reorganization or removal of things in the old releases that made ongoing maintenance more difficult than it needed to be, were inconsistent, inefficient, etc.

but I ran into these two issues when running the first
of some 2.4.2.4 code under 2.5.1.5 (still using the wxPython namespace):

* The "old" wxDC.DrawBitmap method doesn't appear to be one of those that
  maintained the old x,y signature rather than a wxPoint.

Both DrawBitmap and DrawBitmapXY are present:

>>> import wx
>>> wx.DC.DrawBitmap.__doc__
'DrawBitmap(Bitmap bmp, Point pt, bool useMask=False)'
>>> wx.DC.DrawBitmapXY.__doc__
'DrawBitmapXY(Bitmap bmp, int x, int y, bool useMask=False)'

The compatibility class wx.DC_old uses DrawBitmapXY for the DrawBitmap name:

>>> wx.DC_old.DrawBitmap.__doc__
'DrawBitmapXY(Bitmap bmp, int x, int y, bool useMask=False)'
>>>

If you import via the old namespace then the wxDC_old class is used for the wxDC name so you get the compatibility version of the methods automatically:

>>> import wxPython.wx
>>> wxPython.wx.wxDC
<class 'wx.gdi.DC_old'>
>>> wxPython.wx.wxDC.DrawBitmap.__doc__
'DrawBitmapXY(Bitmap bmp, int x, int y, bool useMask=False)'
>>>

* wxSizer.AddMany() now appears to require that for spacers the size
  be a tuple.

Or a wxSize, or any two integer sequence. This is mentioned in the MigrationGuide.

This is different than 2.4.2.4 and from my perspective
  different than the existing docs for 2.5.1.5 since they show the Add
  for a spacer with just distinct x and y parameters.

The original intent was to have the new Python-specific docs ready for all the 2.5 releases so I didn't keep the Python notes in the C++ docs up to date. The new docs are still progressing, but until then the when things don't work as expected be sure to check the __doc__ strings.

It looks like
  the problem might be how the wrapper for Add() itself changed.

This change actually originated in 2.4, but there was some ugly code in place to allow either a wxSize or individual parameters to be used. The ugly code was removed for this release and the wrappers made much simpler.

I
  see some special support in the AddMany code (compared to 2.4.2.4)
  to try to handle a simple spacer case, but in my case I have a
  spacer with a proportion argument, so the code ignores that. For
  example, I sometimes have AddMany calls like:

      sizer.AddMany([(0,0,3),
                     (title, 0, wx.wxCENTER, 1),
                     (0,0,1),
                     (hsizer, 0, wx.wxEXPAND),
                     (0,0,1),
                     (go, 0, wx.wxALIGN_CENTER),
                     (msgbox, 6, wx.wxEXPAND|wx.wxALL, 20)])

  Should this still work (based on the docs for wxSizer.Add) or should
  I assume the signature for Add/AddMany should explicitly use a tuple
  for sizes?

Add() already will require the wx.Size or sequence. The check in AddMany just allows it to treat a 2-element tuple the same as passing a sigle item. For example, this is legal:

     sizer.AddMany([win1, # same as sizer.Add(win1)
                    (5,5), # same as sizer.Add((5,5))
                    (win2, 1, wxEXPAND) # sizer.Add(win2, 1, wxEXPAND)
                   ])

In your example, you are wanting to pass the sizer item (the spacer) with additional parameters. So you would use the same structure as the last line above with (item, *args):

     sizer.AddMany([((0,0), 3),
                    (title, 0, wx.wxCENTER, 1),
                    ((0,0), 1),
                    (hsizer, 0, wx.wxEXPAND),
                    ((0,0), 1),
                    (go, 0, wx.wxALIGN_CENTER),
                    (msgbox, 6, wx.wxEXPAND|wx.wxALL, 20)])

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn <robin@alldunn.com> writes:

The compatibility class wx.DC_old uses DrawBitmapXY for the DrawBitmap name:

>>> wx.DC_old.DrawBitmap.__doc__
'DrawBitmapXY(Bitmap bmp, int x, int y, bool useMask=False)'
>>>

If you import via the old namespace then the wxDC_old class is used
for the wxDC name so you get the compatibility version of the methods
automatically:

>>> import wxPython.wx
>>> wxPython.wx.wxDC
<class 'wx.gdi.DC_old'>
>>> wxPython.wx.wxDC.DrawBitmap.__doc__
'DrawBitmapXY(Bitmap bmp, int x, int y, bool useMask=False)'
>>>

That's really strange - I see the above too, but my code fails unless
I switched my DrawBitmap calls to the wxPoint approach.

Ah, I think I figured it out - the DC in question is coming from a
paint event and thus from event.GetDC() call, which is returning a
wx.gdi.DC object, which must be the newer style (yeah, DrawBitmap maps
to DrawBitmap and not DrawBitmapXY).

There's probably no realistic way to handle that in a backwards
compatible manner, but it does highlight a difficulty in writing
drawing code that is compatible between 2.4 and 2.5 - e.g., even if
you stick with the old bindings I'm not sure how I'd code this to work
in either release - I guess I'd have to conditionally test for the
DrawBitmapXY method existence and use that when available.

Perhaps a comment about this could be added to the migration guide,
since my perception from it would be that drawing would be fine as
long as I stuck with the classic namespace?

> * wxSizer.AddMany() now appears to require that for spacers the size
> be a tuple.

Or a wxSize, or any two integer sequence. This is mentioned in the
MigrationGuide.

Ok, that's really embarrassing - I read through the MigrationGuide
first, but somehow that line didn't stay with me through the code
testing. My apologies.

Since the underlying change originated in 2.4, and from a quick test
it seems I can use the tuple format even back in 2.4 that looks like
an easy way to stay compatible.

-- David

David Bolen wrote:

That's really strange - I see the above too, but my code fails unless
I switched my DrawBitmap calls to the wxPoint approach.

Ah, I think I figured it out - the DC in question is coming from a
paint event and thus from event.GetDC() call, which is returning a
wx.gdi.DC object, which must be the newer style (yeah, DrawBitmap maps
to DrawBitmap and not DrawBitmapXY).

Right, I didn't think about that case. :frowning:

There's probably no realistic way to handle that in a backwards
compatible manner,

Probably not, but I'll think about it.

but it does highlight a difficulty in writing
drawing code that is compatible between 2.4 and 2.5 - e.g., even if
you stick with the old bindings I'm not sure how I'd code this to work
in either release - I guess I'd have to conditionally test for the
DrawBitmapXY method existence and use that when available.

Maybe something like this?

  dc = event.GetDC()
  if wx.VERSION < (2,5):
    dc.DrawBitmapXY = dc.DrawBitmap
  dc.DrawBitmapXY(bmp, x, y)

Perhaps a comment about this could be added to the migration guide,

Yep, will do.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!