wx.lib.scrolledpanel and popupctl problem

I have a problem with a custom popup control of mine, but I can reproduce it with popupctl.

Attached is a small sample app it has two popup controls (in my case there are more, 3 to 4).

To recreate problem
- resize window until only the left control is shown
- scroll the right control into view
- click on the bottom to show the popup

At this point the window scrolls but the popup is not shown, something seems to eat the EVT_BUTTON event.

I see with with SizedScrolledPanel (code is commented in attached) but I also see it with ScrolledPanel (which is active in attached sample).

Anyone has an idea of what is causing this and how to correct it.

Werner

P.S. popup of second popup control is also messed up.

popupissue.py (3.06 KB)

Did some more digging on this and it seems to be due to the OnChildFocus handling in wx.lib.scrolledpanel, if I comment the bind for this then the problem goes away.

There is also a flag which controls "scrollIntoView" with by default is True, setting is in my code does the trick too.

Changing the event handler in wx.lib.scolledpanel might also make this work better out of the box, but I am not sure if the suggested change below wouldn't have some side effects I don't see.

From:

     def OnChildFocus(self, evt):
         """
         If the child window that gets the focus is not fully visible,
         this handler will try to scroll enough to see it.
         """
         child = evt.GetWindow()
         if self.scrollIntoView:
             self.ScrollChildIntoView(child)
             evt.Skip()

To:
     def OnChildFocus(self, evt):
         """
         If the child window that gets the focus is not fully visible,
         this handler will try to scroll enough to see it.
         """
         child = evt.GetWindow()
         if self.scrollIntoView and not child.IsShown():
             self.ScrollChildIntoView(child)
             evt.Skip()

Werner

···

On 11/24/2011 09:45 AM, werner wrote:

I have a problem with a custom popup control of mine, but I can reproduce it with popupctl.

Attached is a small sample app it has two popup controls (in my case there are more, 3 to 4).

To recreate problem
- resize window until only the left control is shown
- scroll the right control into view
- click on the bottom to show the popup

At this point the window scrolls but the popup is not shown, something seems to eat the EVT_BUTTON event.

I see with with SizedScrolledPanel (code is commented in attached) but I also see it with ScrolledPanel (which is active in attached sample).

Anyone has an idea of what is causing this and how to correct it.

Werner

P.S. popup of second popup control is also messed up.

I think IsShown only reports the state with regards to Show()/Hide(), not whether the window is not visible because of the scrolling of the parent. So I don't think that your proposed change is doing what you think it is doing.

A probable workaround for your specific use case you could catch the child focus event yourself, check if the child is a button and only call Skip if it isn't. Then the focus events for buttons will not cause the scrolled panel to scroll.

···

On 11/24/11 2:10 AM, werner wrote:

On 11/24/2011 09:45 AM, werner wrote:

I have a problem with a custom popup control of mine, but I can
reproduce it with popupctl.

Attached is a small sample app it has two popup controls (in my case
there are more, 3 to 4).

To recreate problem
- resize window until only the left control is shown
- scroll the right control into view
- click on the bottom to show the popup

At this point the window scrolls but the popup is not shown, something
seems to eat the EVT_BUTTON event.

I see with with SizedScrolledPanel (code is commented in attached) but
I also see it with ScrolledPanel (which is active in attached sample).

Anyone has an idea of what is causing this and how to correct it.

Werner

P.S. popup of second popup control is also messed up.

Did some more digging on this and it seems to be due to the OnChildFocus
handling in wx.lib.scrolledpanel, if I comment the bind for this then
the problem goes away.

There is also a flag which controls "scrollIntoView" with by default is
True, setting is in my code does the trick too.

Changing the event handler in wx.lib.scolledpanel might also make this
work better out of the box, but I am not sure if the suggested change
below wouldn't have some side effects I don't see.

--
Robin Dunn
Software Craftsman

Hi Robin,

...

Changing the event handler in wx.lib.scolledpanel might also make this
work better out of the box, but I am not sure if the suggested change
below wouldn't have some side effects I don't see.

I think IsShown only reports the state with regards to Show()/Hide(), not whether the window is not visible because of the scrolling of the parent. So I don't think that your proposed change is doing what you think it is doing.

You are right, should have figured that out myself too:-( .

A probable workaround for your specific use case you could catch the child focus event yourself, check if the child is a button and only call Skip if it isn't. Then the focus events for buttons will not cause the scrolled panel to scroll.

For the moment I think I get away with just doing "scrolledPanel.scrollIntoView = False", but will give the focus event a try too.

BTW, any idea why the second calendar popup is not correctly placed in the popup window? It is shifted to the right.

Using WIT I can see that "self.win" of the second popup gets a pos set of "pos = (123, 0)" but I can't figure out what/who is setting this as it should be (0, 0), i.e. if I do in the WIT a SetPosition((0, 0)) then it pops correctly.

Werner

···

On 12/12/2011 07:43 PM, Robin Dunn wrote: