Phoenix findings

Hi (Robin),

I have finally be able to recompile Phoenix to the latest SVN version.
While testing to port the remaining of AGW to Phoenix, I found the
following issues:

1. wx.ADJUST_MINSIZE (references in wx.lib.inspection, for example)
raises an AttributeError
2. Same for wx.WK_PRIOR, i.e.:

E:\Phoenix\AGW>python CustomTreeCtrl.py
Traceback (most recent call last):
  File "CustomTreeCtrl.py", line 90, in <module>
    wx.WXK_PRIOR : "WXK_PRIOR",
AttributeError: 'module' object has no attribute 'WXK_PRIOR'

Small things, I'll continue to do some more testing tomorrow if I get some time.

···

--
Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://www.infinity77.net

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

I have done some more porting/testing:

1. wx.WXK_PRIOR, wx.WXK_NEXT, wx.WXK_NUMPAD_PRIOR, wx.WXK_NUMPAD_NEXT
all raise an AttributeError (maybe they have been removed altogether
from wxWidgets);
2. FlatMenu uses wx.StopWatch, which seems to be missing;
3. I am not sure how to replace the (now non-existing) method
wx.adv.SashLayoutWindow.SizeWindows (I use it in the FoldPanelBar
demo). Maybe I am just looking in the wrong place or doing the wrong
thing;
4. AquaButton, GradientButton and everything else that uses the
following OnPaint initialization:

    def OnPaint(self, event):
        """
        Handles the ``wx.EVT_PAINT`` event for :class:`GradientButton`.

        :param `event`: a :class:`PaintEvent` event to be processed.
        """

        dc = wx.BufferedPaintDC(self)
        gc = wx.GraphicsContext.Create(dc)

does not display anything. I remember hitting this problem a while
back but I can't figure out what I am doing wrong.

5. wx.SetCursor raises an AttributeError, although I can see it in the
wxWidgets documentation:

http://docs.wxwidgets.org/trunk/group__group__funcmacro__gdi.html#ga04d90db090918ad96448b5603d89617b

Probably I should just use wx.Window.SetCursor, although I am not sure
it is a global setting as it was for wx.SetCursor.

6. wx.USE_UNICODE is gone, as I assume that now everything is unicode
anyway, so I can get rid of that check.

7. When I try to run the ShortcutEditor demo (cleaned from a couple of
harmless DeprecationWarnings), I get a Windows "segmentation fault",
with the usual message dialog telling me that Python has stopped
working...

8. FlatMenu also uses wx.GetAccelFromString, which has been removed in
wxWidgets: what is the recommended way to get the accelerator out of a
menu label?

9. The AGW demos needed heavy modifications to be somehow compatible
with Phoenix: what is the recommended approach to deal with Classic
and Phoenix at the same time? Should we have two separate "demos"
repositories for Phoenix and Classic or should I pepper the code with
"if" conditions to distinguish Phoenix from Classic?

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

···

On 18 December 2012 22:48, Andrea Gavana wrote:

Hi (Robin),

I have finally be able to recompile Phoenix to the latest SVN version.
While testing to port the remaining of AGW to Phoenix, I found the
following issues:

1. wx.ADJUST_MINSIZE (references in wx.lib.inspection, for example)
raises an AttributeError
2. Same for wx.WK_PRIOR, i.e.:

E:\Phoenix\AGW>python CustomTreeCtrl.py
Traceback (most recent call last):
  File "CustomTreeCtrl.py", line 90, in <module>
    wx.WXK_PRIOR : "WXK_PRIOR",
AttributeError: 'module' object has no attribute 'WXK_PRIOR'

Small things, I'll continue to do some more testing tomorrow if I get some time.

Hi (Robin),

Hi (Robin),

I have finally be able to recompile Phoenix to the latest SVN version.
While testing to port the remaining of AGW to Phoenix, I found the
following issues:

1. wx.ADJUST_MINSIZE (references in wx.lib.inspection, for example)
raises an AttributeError
2. Same for wx.WK_PRIOR, i.e.:

E:\Phoenix\AGW>python CustomTreeCtrl.py
Traceback (most recent call last):
  File "CustomTreeCtrl.py", line 90, in <module>
    wx.WXK_PRIOR : "WXK_PRIOR",
AttributeError: 'module' object has no attribute 'WXK_PRIOR'

Small things, I'll continue to do some more testing tomorrow if I get some time.

I have done some more porting/testing:

1. wx.WXK_PRIOR, wx.WXK_NEXT, wx.WXK_NUMPAD_PRIOR, wx.WXK_NUMPAD_NEXT
all raise an AttributeError (maybe they have been removed altogether
from wxWidgets);
2. FlatMenu uses wx.StopWatch, which seems to be missing;
3. I am not sure how to replace the (now non-existing) method
wx.adv.SashLayoutWindow.SizeWindows (I use it in the FoldPanelBar
demo). Maybe I am just looking in the wrong place or doing the wrong
thing;
4. AquaButton, GradientButton and everything else that uses the
following OnPaint initialization:

    def OnPaint(self, event):
        """
        Handles the ``wx.EVT_PAINT`` event for :class:`GradientButton`.

        :param `event`: a :class:`PaintEvent` event to be processed.
        """

        dc = wx.BufferedPaintDC(self)
        gc = wx.GraphicsContext.Create(dc)

does not display anything. I remember hitting this problem a while
back but I can't figure out what I am doing wrong.

5. wx.SetCursor raises an AttributeError, although I can see it in the
wxWidgets documentation:

wxWidgets: Graphics Device Interface (GDI)

Probably I should just use wx.Window.SetCursor, although I am not sure
it is a global setting as it was for wx.SetCursor.

6. wx.USE_UNICODE is gone, as I assume that now everything is unicode
anyway, so I can get rid of that check.

7. When I try to run the ShortcutEditor demo (cleaned from a couple of
harmless DeprecationWarnings), I get a Windows "segmentation fault",
with the usual message dialog telling me that Python has stopped
working...

8. FlatMenu also uses wx.GetAccelFromString, which has been removed in
wxWidgets: what is the recommended way to get the accelerator out of a
menu label?

9. The AGW demos needed heavy modifications to be somehow compatible
with Phoenix: what is the recommended approach to deal with Classic
and Phoenix at the same time? Should we have two separate "demos"
repositories for Phoenix and Classic or should I pepper the code with
"if" conditions to distinguish Phoenix from Classic?

Few others I found:

1) wx.DIALOG_NO_PARENT raises an AttributeError:

http://docs.wxwidgets.org/trunk/classwx_dialog.html

2) In wx.lib.agw.aui, I have a custom subclass of wx.DragImage to
display notebook tabs being dragged around. I initialize it like this:

self._drag_image = TabDragImage(self, page, tab_button.cur_state, self._art)

And it is initialized correctly. However, as soon as I call BeginDrag():

self._drag_image.BeginDrag(wx.Point(0,0), self, self.GetParent())

Then self._drag_image is reset to None. If I don't call BeginDrag()
then everything is fine.

3. It appears that now DC.SetClippingRegion does not accept a regions
as input parameters (only a 4-element tuple or a wx.Rect), so all the
fancy drawings of tabs in AuiNotebook is a bit out of reach. What is
the alternative way of restricting drawing to a non-rectangular
region?

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

···

On 19 December 2012 22:22, Andrea Gavana wrote:

On 18 December 2012 22:48, Andrea Gavana wrote:

Hi (Robin),

Hi (Robin),

I have finally be able to recompile Phoenix to the latest SVN version.
While testing to port the remaining of AGW to Phoenix, I found the
following issues:

1. wx.ADJUST_MINSIZE (references in wx.lib.inspection, for example)
raises an AttributeError

wxADJUST_MINSIZE is inside a "#if WXWIN_COMPATIBILITY_2_8" block so it should probably not be put in the wx docs. I'll add an item for it in an etg script instead.

I have done some more porting/testing:

1. wx.WXK_PRIOR, wx.WXK_NEXT, wx.WXK_NUMPAD_PRIOR, wx.WXK_NUMPAD_NEXT
all raise an AttributeError (maybe they have been removed altogether
from wxWidgets);

These are in WXWIN_COMPATIBILITY_2_6 blocks. That is old enough that I think they should not be included any more at all. WXK_*PAGEUP and WXK_*PAGEDOWN can be used instead.

2. FlatMenu uses wx.StopWatch, which seems to be missing;

I'll add it.

3. I am not sure how to replace the (now non-existing) method
wx.adv.SashLayoutWindow.SizeWindows (I use it in the FoldPanelBar
demo). Maybe I am just looking in the wrong place or doing the wrong
thing;

It looks like that and some other methods were left out of the wx docs, so nothing was generated for them in Phoenix. I'll get them added.

4. AquaButton, GradientButton and everything else that uses the
following OnPaint initialization:

     def OnPaint(self, event):
         """
         Handles the ``wx.EVT_PAINT`` event for :class:`GradientButton`.

         :param `event`: a :class:`PaintEvent` event to be processed.
         """

         dc = wx.BufferedPaintDC(self)
         gc = wx.GraphicsContext.Create(dc)

does not display anything. I remember hitting this problem a while
back but I can't figure out what I am doing wrong.

It's a bug in sip's and/or my code. I misunderstood how the KeepReference sip annotation works. I want to ensure that the dc lives as long as the gc and won't be garbage collected before the gc is. That is in case code like this is used:

  gc = wx.GraphicsContext.Create(wx.BufferedPaintDC(self))

Without saving an extra reference to the dc then the dc will flush its buffer to the screen right after that line of code and the gc will end up with an invalid DC.

However since Create is a static method and there is no self to associate the extra reference with then SIP's KeepReference argument annotation is causing that extra reference to be leaked and so the buffered dc will never flush it's bitmap to the screen. It looks like I'll need to find another way to do what I need there...

5. wx.SetCursor raises an AttributeError, although I can see it in the
wxWidgets documentation:

I have an item on my ToDo list to track down the various global functions and some other miscellaneous items that are not wrapped yet. This is one of those items. It will get added soonish.

Probably I should just use wx.Window.SetCursor, although I am not sure
it is a global setting as it was for wx.SetCursor.

No, it will just set the cursor for the given window. Most of the time that is what you want, but if you need it done no matter where the cursor is located then it is not enough.

6. wx.USE_UNICODE is gone, as I assume that now everything is unicode
anyway, so I can get rid of that check.

Yes.

7. When I try to run the ShortcutEditor demo (cleaned from a couple of
harmless DeprecationWarnings), I get a Windows "segmentation fault",
with the usual message dialog telling me that Python has stopped
working...

Do you have any general idea where the crash might be happening or what might be going on in the application at the time?

8. FlatMenu also uses wx.GetAccelFromString, which has been removed in
wxWidgets: what is the recommended way to get the accelerator out of a
menu label?

It looks like this should work:

  accel = wx.AcceleratorEntry()
  accel.FromString(label)

9. The AGW demos needed heavy modifications to be somehow compatible
with Phoenix: what is the recommended approach to deal with Classic
and Phoenix at the same time? Should we have two separate "demos"
repositories for Phoenix and Classic or should I pepper the code with
"if" conditions to distinguish Phoenix from Classic?

I've been working under the assumption that there would be separate demo code, and also that the demo framework itself would be cleaned up and improved at the same time. (In other words, to be less of a jumble of hacked up features bolted together in a haphazard manner. :wink: ) But I haven't given it much thought beyond that and almost no work. So far when I've needed something more than unit tests I've been adding something to the samples folder.

Few others I found:

1) wx.DIALOG_NO_PARENT raises an AttributeError:

wxWidgets: wxDialog Class Reference

It was described in the docs, but the actual declaration of the flag was missing from the interface file. Fixed.

2) In wx.lib.agw.aui, I have a custom subclass of wx.DragImage to
display notebook tabs being dragged around. I initialize it like this:

self._drag_image = TabDragImage(self, page, tab_button.cur_state, self._art)

And it is initialized correctly. However, as soon as I call BeginDrag():

self._drag_image.BeginDrag(wx.Point(0,0), self, self.GetParent())

Then self._drag_image is reset to None. If I don't call BeginDrag()
then everything is fine.

Do you override BeginDrag in your subclass? If so does it make any modifications to self? I don't see how something like that could happen from the wrapped C++ code.

3. It appears that now DC.SetClippingRegion does not accept a regions
as input parameters (only a 4-element tuple or a wx.Rect), so all the
fancy drawings of tabs in AuiNotebook is a bit out of reach. What is
the alternative way of restricting drawing to a non-rectangular
region?

It looks like it is possible with the SetDeviceClippingRegion. I'm not sure why it has been split out to a new method name, although it makes sense if the SetClippingRegion(region) could not be made to work correctly with logical coordinates.

···

On 12/20/12 2:32 AM, Andrea Gavana wrote:

On 19 December 2012 22:22, Andrea Gavana wrote:

On 18 December 2012 22:48, Andrea Gavana wrote:

--
Robin Dunn
Software Craftsman

Hi Robin,

4. AquaButton, GradientButton and everything else that uses the
following OnPaint initialization:

     def OnPaint(self, event):
         """
         Handles the ``wx.EVT_PAINT`` event for :class:`GradientButton`.

         :param `event`: a :class:`PaintEvent` event to be processed.
         """

         dc = wx.BufferedPaintDC(self)
         gc = wx.GraphicsContext.Create(dc)

does not display anything. I remember hitting this problem a while
back but I can't figure out what I am doing wrong.

It's a bug in sip's and/or my code. I misunderstood how the KeepReference
sip annotation works. I want to ensure that the dc lives as long as the gc
and won't be garbage collected before the gc is. That is in case code like
this is used:

        gc = wx.GraphicsContext.Create(wx.BufferedPaintDC(self))

Without saving an extra reference to the dc then the dc will flush its
buffer to the screen right after that line of code and the gc will end up
with an invalid DC.

However since Create is a static method and there is no self to associate
the extra reference with then SIP's KeepReference argument annotation is
causing that extra reference to be leaked and so the buffered dc will never
flush it's bitmap to the screen. It looks like I'll need to find another
way to do what I need there...

It seems to be working now, at least for AquaButton, thanks for the
quick patch. I'll test GradientButton soon.

5. wx.SetCursor raises an AttributeError, although I can see it in the
wxWidgets documentation:

I have an item on my ToDo list to track down the various global functions
and some other miscellaneous items that are not wrapped yet. This is one of
those items. It will get added soonish.

Thanks, it's in there now, I'll revert back to using wx.SetCursor for
those few modules needing it.

7. When I try to run the ShortcutEditor demo (cleaned from a couple of
harmless DeprecationWarnings), I get a Windows "segmentation fault",
with the usual message dialog telling me that Python has stopped
working...

Do you have any general idea where the crash might be happening or what
might be going on in the application at the time?

Not yet, but I am getting the same crash with FlatMenu - as soon as
the menu window is popped up. I'll do some more debugging and see if I
can nail it down.

8. FlatMenu also uses wx.GetAccelFromString, which has been removed in
wxWidgets: what is the recommended way to get the accelerator out of a
menu label?

It looks like this should work:

        accel = wx.AcceleratorEntry()
        accel.FromString(label)

That did the trick, thanks.

2) In wx.lib.agw.aui, I have a custom subclass of wx.DragImage to
display notebook tabs being dragged around. I initialize it like this:

self._drag_image = TabDragImage(self, page, tab_button.cur_state,
self._art)

And it is initialized correctly. However, as soon as I call BeginDrag():

self._drag_image.BeginDrag(wx.Point(0,0), self, self.GetParent())

Then self._drag_image is reset to None. If I don't call BeginDrag()
then everything is fine.

Do you override BeginDrag in your subclass? If so does it make any
modifications to self? I don't see how something like that could happen
from the wrapped C++ code.

No, I don't override any method except the __init__ one. I'll
investigate further,.

3. It appears that now DC.SetClippingRegion does not accept a regions
as input parameters (only a 4-element tuple or a wx.Rect), so all the
fancy drawings of tabs in AuiNotebook is a bit out of reach. What is
the alternative way of restricting drawing to a non-rectangular
region?

It looks like it is possible with the SetDeviceClippingRegion. I'm not sure
why it has been split out to a new method name, although it makes sense if
the SetClippingRegion(region) could not be made to work correctly with
logical coordinates.

Thanks, that did the trick again.

I have found something else, which seems a bit funny to me but maybe
it's a new development I have missed. Consider the following:

import wx
wx.version()

'2.9.5.80 msw (phoenix)'

wx.Size(20, 22) + wx.Size(6, 4)

wx.Point(26, 26)

???

I am not clear if adding two wx.Size objects now returns a wx.Point
object or there has been some other changes. It's a bit problematic as
the ribbon code extensively uses addition between sizes and then
manipulation of them (via SetWidth/SetHeight etc...), which raise
AttributeError on a wx.Point.

This is with SVN revision 73273, i.e. a day old more or less, on
Windows 7 64 bit and Python 2.7.3.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

···

On 22 December 2012 09:00, Robin Dunn wrote:

On 12/20/12 2:32 AM, Andrea Gavana wrote:

It is an unfortunate side-effect of being able to be so flexible with Python.

The way that function overloads (the operator+() function in this case) are handled by the generated code is that each function signature is tested with the actual parameters passed, and the first one that matches is called. Now since both wxSize and wxPoint can be constructed from a 2-element sequence, and since both also provide the magic methods needed to make them look like 2-element sequences, then that can cause some confusion in the wrapper code. They basically become mostly interchangeable. In this case it is testing for matches in this order:

     wxPoint operator+(const wxPoint& p, const wxSize& s);
     wxPoint operator+(const wxPoint& p1, const wxPoint& p2);
     wxPoint operator+(const wxSize& s, const wxPoint& p);
     wxSize operator+(const wxSize& s1, const wxSize& s2);

but because of the bidirectional 2-element sequence typemaps I think that only the first one will ever actually be called.

I can fix this by using a sip annotation that tells it that the parameter types passed to these functions must match exactly and can't be converted from something else, but then things like "wx.Point(1,1) + (2,2)" will not work, and I know I have some of those in my projects so I expect that others do too.

Another fix would be to remove the indexing magic methods from the point and size classes, but that would break code that uses things like pos[0], pos[1] to get the x and y values from a wx.Point, and there is a lot of code out there like that.

I'll give this some more thought to see if there might be some other way to do the right thing without losing existing functionality, but in the meantime as a workaround you can use something like this to force the value back to a wx.Size:

     size = wx.Size( *(size1 + size2))

···

On 12/27/12 5:36 AM, Andrea Gavana wrote:

I have found something else, which seems a bit funny to me but maybe
it's a new development I have missed. Consider the following:

import wx
wx.version()

'2.9.5.80 msw (phoenix)'

wx.Size(20, 22) + wx.Size(6, 4)

wx.Point(26, 26)

???

I am not clear if adding two wx.Size objects now returns a wx.Point
object or there has been some other changes. It's a bit problematic as
the ribbon code extensively uses addition between sizes and then
manipulation of them (via SetWidth/SetHeight etc...), which raise
AttributeError on a wx.Point.

--
Robin Dunn
Software Craftsman

It is an unfortunate side-effect of being able to be so flexible with
Python.

The way that function overloads (the operator+() function in this case) are
handled by the generated code is that each function signature is tested with
the actual parameters passed, and the first one that matches is called. Now
since both wxSize and wxPoint can be constructed from a 2-element sequence,
and since both also provide the magic methods needed to make them look like
2-element sequences, then that can cause some confusion in the wrapper code.
They basically become mostly interchangeable. In this case it is testing
for matches in this order:

    wxPoint operator+(const wxPoint& p, const wxSize& s);
    wxPoint operator+(const wxPoint& p1, const wxPoint& p2);
    wxPoint operator+(const wxSize& s, const wxPoint& p);
    wxSize operator+(const wxSize& s1, const wxSize& s2);

but because of the bidirectional 2-element sequence typemaps I think that
only the first one will ever actually be called.

hmm -- I wonder if there's a way to force it to check first for
explicit C++ types, then for python "duck types" . /something like:

if type(p1) is wx.Size or type(p2) is wx.Size:
   call_the_wx.Size_option

I can fix this by using a sip annotation that tells it that the parameter
types passed to these functions must match exactly and can't be converted
from something else, but then things like "wx.Point(1,1) + (2,2)" will not
work, and I know I have some of those in my projects so I expect that others
do too.

yeah, that's not good.

oh well, I kind of wonder whether it really makes sense to add a point
to a point, or a point to a size anyway -- the concepts don't really
match.

-Chris

···

On Thu, Dec 27, 2012 at 1:27 PM, Robin Dunn <robin@alldunn.com> wrote:

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Hi Chris,

It is an unfortunate side-effect of being able to be so flexible with
Python.

The way that function overloads (the operator+() function in this case) are
handled by the generated code is that each function signature is tested with
the actual parameters passed, and the first one that matches is called. Now
since both wxSize and wxPoint can be constructed from a 2-element sequence,
and since both also provide the magic methods needed to make them look like
2-element sequences, then that can cause some confusion in the wrapper code.
They basically become mostly interchangeable. In this case it is testing
for matches in this order:

    wxPoint operator+(const wxPoint& p, const wxSize& s);
    wxPoint operator+(const wxPoint& p1, const wxPoint& p2);
    wxPoint operator+(const wxSize& s, const wxPoint& p);
    wxSize operator+(const wxSize& s1, const wxSize& s2);

but because of the bidirectional 2-element sequence typemaps I think that
only the first one will ever actually be called.

hmm -- I wonder if there's a way to force it to check first for
explicit C++ types, then for python "duck types" . /something like:

if type(p1) is wx.Size or type(p2) is wx.Size:
   call_the_wx.Size_option

This was my thought as well: I don't think there are will be so many
people explicitly playing with wx.Size and wx.Point, but adding two
wx.Size and getting a wx.Point as a result is a bit funny.

I can fix this by using a sip annotation that tells it that the parameter
types passed to these functions must match exactly and can't be converted
from something else, but then things like "wx.Point(1,1) + (2,2)" will not
work, and I know I have some of those in my projects so I expect that others
do too.

yeah, that's not good.

oh well, I kind of wonder whether it really makes sense to add a point
to a point, or a point to a size anyway -- the concepts don't really
match.

I would say that they do: after all, this is what you do on a 2D space
of Cartesian coordinates. You add a wx.Point(10, 20) to a wx.Point(5,
5) and you get a wx.Point(15, 25). And if you know what you are doing,
you can safely add a wx.Size to a wx.Size. I agree that mixing
wx.Point with wx.Size doesn't make any sense, but that was not my
original remark. I can of course implement Robin's workaround, but I
am not sure about the intuitiveness of getting a wx.Point out of the
sum of two wx.Size.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

···

On 27 December 2012 22:50, Chris Barker - NOAA Federal wrote:

On Thu, Dec 27, 2012 at 1:27 PM, Robin Dunn <robin@alldunn.com> wrote:

Hi Robin,

a few more I have found:

1. The wx.FindWindowById function is missing, although I can easily
use the wx.Window.FindWindowById static method;
2. wx.EVT_TOGGLEBUTTON raises an AttributeError;
3. It appears wx.BoxSizer doesn't have a SetOrientation method anymore
(not even in wxWidgets). I imagine the only workaround is to rebuild a
new sizer.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://www.infinity77.net

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

And a few more:

4. wx.MenuBar FindItem is missing:

http://docs.wxwidgets.org/trunk/classwx_menu_bar.html#a72a687fc651015d2e5ed13ec08421771

5. The hard crash on ShortcutEditor was caused by this line:

for menuItem in menu.GetMenuItems():

where "menu" is a top menu in a wx.MenuBar. For some reason the
iteration directly on wxList was causing the crash, as it is fixed if
I do this:

for menuItem in list(menu.GetMenuItems()):

6. Similar behaviour of wxList in wx.Sizer.GetChildren(): if I lookup
one sizer item like this:

item = sizer.GetChildren()[-1]

I get an IndexError. A solution was to use

item = list(sizer.GetChildren())[-1]

Minor things overall.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

···

On 28 December 2012 11:17, Andrea Gavana wrote:

Hi Robin,

a few more I have found:

1. The wx.FindWindowById function is missing, although I can easily
use the wx.Window.FindWindowById static method;
2. wx.EVT_TOGGLEBUTTON raises an AttributeError;
3. It appears wx.BoxSizer doesn't have a SetOrientation method anymore
(not even in wxWidgets). I imagine the only workaround is to rebuild a
new sizer.

oh well, I kind of wonder whether it really makes sense to add a point
to a point, or a point to a size anyway -- the concepts don't really
match.

I would say that they do: after all, this is what you do on a 2D space
of Cartesian coordinates. You add a wx.Point(10, 20) to a wx.Point(5,
5) and you get a wx.Point(15, 25). And if you know what you are doing,
you can safely add a wx.Size to a wx.Size.

I think this is a bit of a clash of static vs. dynamic typing -- in
Python, I'd tend to store anything that requires a pair of values in
tuples: (x1, x2), (or numpy arrays), and then do stuff like adding
them, etc, expecting that the writer of the code knows what they mean.
But in a static language, you generally define things with specific
types -- a point is a point, a size a size, etc.

geometrically, adding "points" isn't well defined -- but adding R2
vectors (also defined by two values) is. So if you want to do that,
you should be using a vector type, not a point type.

But all this makes me think -- let's keep Python Python, and maybe all
those operations should return tuples, rather than wxPoints or
wxSizes, or any other 2-tuple-like object.

I
am not sure about the intuitiveness of getting a wx.Point out of the
sum of two wx.Size.

because there is nothing intuitive about it!

-Chris

···

On Fri, Dec 28, 2012 at 12:50 AM, Andrea Gavana <andrea.gavana@gmail.com> wrote:

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

oh well, I kind of wonder whether it really makes sense to add a point
to a point, or a point to a size anyway -- the concepts don't really
match.

I would say that they do: after all, this is what you do on a 2D space
of Cartesian coordinates. You add a wx.Point(10, 20) to a wx.Point(5,
5) and you get a wx.Point(15, 25). And if you know what you are doing,
you can safely add a wx.Size to a wx.Size.

I think this is a bit of a clash of static vs. dynamic typing -- in
Python, I'd tend to store anything that requires a pair of values in
tuples: (x1, x2), (or numpy arrays), and then do stuff like adding
them, etc, expecting that the writer of the code knows what they mean.
But in a static language, you generally define things with specific
types -- a point is a point, a size a size, etc.

This doesn't apply when you try to port a generic custom control from
wxWidgets to wxPython. I like the flexibility of Python, but the
biggest advantage of the similarity between wxWidgets and wxPython was
the almost perfect interchangeability between large pieces of code.
What run in C++ would run in Python with very, very few modifications.
Now every little piece of code which mixes wx.Point, wx.Size and
wx.Rect needs to be looked at suspiciously.

geometrically, adding "points" isn't well defined -- but adding R2
vectors (also defined by two values) is. So if you want to do that,
you should be using a vector type, not a point type.

See above.

But all this makes me think -- let's keep Python Python, and maybe all
those operations should return tuples, rather than wxPoints or
wxSizes, or any other 2-tuple-like object.

I
am not sure about the intuitiveness of getting a wx.Point out of the
sum of two wx.Size.

because there is nothing intuitive about it!

Might be, but I stand by my previous point: as you won't expect the
sum of two integers to give you a float, you shouldn't expect the sum
of two wx.Size to give you a wx.Point. They are completely different
classes.

Anyway, as I seem unable to get my point across, I'll just shut up.
I'll accept Robin's explanation and I'll get a move on.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

···

On 28 December 2012 18:04, Chris Barker - NOAA Federal wrote:

On Fri, Dec 28, 2012 at 12:50 AM, Andrea Gavana <andrea.gavana@gmail.com> wrote:

But in a static language, you generally define things with specific
types -- a point is a point, a size a size, etc.

This doesn't apply when you try to port a generic custom control from
wxWidgets to wxPython. I like the flexibility of Python, but the
biggest advantage of the similarity between wxWidgets and wxPython was
the almost perfect interchangeability between large pieces of code.
What run in C++ would run in Python with very, very few modifications.
Now every little piece of code which mixes wx.Point, wx.Size and
wx.Rect needs to be looked at suspiciously.

Perhaps returning a more dynamic python type from all operations would
make this easier -- anything that takes a wxPoint or wxSize (or??)
also takes a 2-tuple...

Though I guess it would get ugly if you wanted to do something.x, etc.

am not sure about the intuitiveness of getting a wx.Point out of the
sum of two wx.Size.

because there is nothing intuitive about it!

Might be, but I stand by my previous point: as you won't expect the
sum of two integers to give you a float, you shouldn't expect the sum
of two wx.Size to give you a wx.Point. They are completely different
classes.

Anyway, as I seem unable to get my point across,

no -- you did -- I was intending to agree with you about getting a
wx.Point out of a wx.Size operation! It makes no sense, it's an
artifact of how the wrappers translate types, and in what order.

It could clearly be done better -- it's a question of how much it's
worth over-riding the auto-generated wrappers.

I'll accept Robin's explanation and I'll get a move on.

well, little choice at this point anyway.

-Chris

···

On Fri, Dec 28, 2012 at 2:19 PM, Andrea Gavana <andrea.gavana@gmail.com> wrote:

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Hi Robin,

a few more I have found:

1. The wx.FindWindowById function is missing, although I can easily
use the wx.Window.FindWindowById static method;

Fixed.

2. wx.EVT_TOGGLEBUTTON raises an AttributeError;

Fixed.

3. It appears wx.BoxSizer doesn't have a SetOrientation method anymore
(not even in wxWidgets). I imagine the only workaround is to rebuild a
new sizer.

It is still there, just missing from the wx documentation. Fixed.

And a few more:

4. wx.MenuBar FindItem is missing:

wxWidgets: wxMenuBar Class Reference

Done. I also added FindItemById, which is what it was called in Classic. Find item returns the item and the menu it was found in, and FindItemById returns just the item. I also did the same for wx.Menu.

5. The hard crash on ShortcutEditor was caused by this line:

for menuItem in menu.GetMenuItems():

where "menu" is a top menu in a wx.MenuBar. For some reason the
iteration directly on wxList was causing the crash, as it is fixed if
I do this:

for menuItem in list(menu.GetMenuItems()):

Weird. list() should be using the same iterator to make the list, and using a list comprehension also works without crashing:

     items = [i for i in m.GetMenuItems()]

But I can also duplicate the crash with normal for-loop iteration.

Ok, I've figured it out. Since the GetMenuItems C++ method is const then SIP was creating a temporary copy of the list object to return to Python. Since it is only used to fetch the iterator then that temp object was destroyed before the iterator was finished, causing the crash. I've fixed it so instead of creating the copy it will just wrap the same list object returned from the method.

6. Similar behaviour of wxList in wx.Sizer.GetChildren(): if I lookup
one sizer item like this:

item = sizer.GetChildren()[-1]

I get an IndexError. A solution was to use

item = list(sizer.GetChildren())[-1]

The __getitem__ method in the wxList wrapper classes only know how to use indexes of 0..N, they can't do slicing or negative indexing. This should be the same as in Classic. They probably could be made to handle negative indexes, but currently the right answer is to convert to a real list first like what you did.

I also have a fix for the size+size issue. By moving the math functions to be methods rather than global functions the type of the left operand now determines which method is called. The only thing that was lost was the ability to do "intVal * sizeOrPoint" but "sizeOrPoint * intValue" still works, and nobody was probably using this anyway since Classic doesn't support either, so not a great loss.

···

On 12/28/12 3:37 AM, Andrea Gavana wrote:

On 28 December 2012 11:17, Andrea Gavana wrote:

--
Robin Dunn
Software Craftsman