resizing sub-panels based on expanding controls

Since it is the children of the panel that have changing best sizes and need to have their layout redone, then you should call self.pnl.Layout here instead of self.Layout. The layout of the frame's children (just the top-level panel) does not need to change at all.

BTW, the ExpandoTextCtrl has an event (EVT_ETC_LAYOUT_NEEDED) that it emits when its best size is changing so you can also use that to know when a layout is needed.

···

On 2/7/12 7:05 PM, luvspython wrote:

All,
     I am unable to get my head around how to have multiple sibling sub-
panels expand as needed, and would greatly appreciate advice on how to
accomplish this.

     In my real app, I have a Panel class containing a
UltimateListCtrl, and I have a stack of these panel objects in a
parent panel. I want each subpanel to take only as much space as
required to show all rows in the list control (i.e., avoiding a
vertical scrollbar), and no more space than that (i.e., I don't want a
non-zero proportion when it's added to the parent's sizer) and I have
code that figures out the necessary vertical height to accomplish that
and sets the height of the panel. So the panel grows as I add rows.
This all works when I have a single such listctrl-panel.

     But things don't work when I have a stack of such panels; they
just don't grow.

     Below is a simplified example. It doesn't use my listctrl-panel
because the demo gets big just with the complexity of adding rows to a
listctrl, so the panel in the example below uses an ExpandoTextCtrl
instead. The subpanels are colored differerently to make things more
obvious, and it adds text to different subpanels every few seconds.

     There are some commented-out lines that only show a few of the
many things I've tried, to no avail.

     What I WANT to happen is as each sub-panel's Expando grows
vertically, that colored subpanel should grow so the entire Expando
shows.

     Any help will be GREATLY appreciated !

         def addMore(self):
             self.pnlNum = (self.pnlNum + 1) % 3
             pnl = [self.expPnl1, self.expPnl2, self.expPnl3]
[self.pnlNum]
             pnl.AddText()

             wx.CallLater(3000, self.addMore)
             self.Layout()

--
Robin Dunn
Software Craftsman

Robin,
     You're right, naturally. Thank you very much, for this and for
all you do for all the folks in this group.

     A general question: I guess I was under the impression that when
a widget changes, the
changes propagate up the hierarchy when sizers are used. Could you
give me/us
any general guideline as to when and what changes automatically
propagate up, or down, or whether they never do?

They never do. All that happens is that the widget's size related attributes (best size and/or min size) are changed, but nothing else will happen until the next time a Layout() of the sizer managing that widget is done.

     Similarly, I assumed that issuing a SIZE_EVENT (SendSizeEvent)
would cause the sizers further up the
hierarchy to do their thing. Is that not the case? If not, what
really does SendSizeEvent cause?

It simply sends an EVT_SIZE event to the window you call it on. What happens next depends on the type of window, whether it has a sizer, whether your program binds an EVT_SZIE handler or if the default event handler is run, etc. In the typical case like what we're discussing here the default handler simply calls the window's Layout method. That will tell the sizer to recalculate the layout of the window's children and to move/size them as needed. If any of those children change size then they will each get their own EVT_SIZE event also and if they have sizers then their Layout() is called, and so on.

If you want a change in size requirements to "bubble up" to the top level window then the best way to deal with that is to call the top level window's Fit() method, or some intermediate window's Layout() method. There will likely need to be sizers used in all the windows up to that point in order to get the required sizes to work as expected. But the point is that it is not automatic, you need to do something in your code, like call Layout or Fit, at the time that your code changes the size requirements of some widget.

When bubbling-up size changes (with Fit or whatever) I recommend trying to use a lower level of coupling between the deeply nested widgets and their (great)grandparents where the Layout or Fit needs to take place. In other words, the widget where the change happens normally shouldn't have to know what context it is used in and know that its great-great-grandparent needs to call Layout every time the widget wants to use a different amount of space. One easy way to do that is to use an event to indicate that a layout is needed, like the ExpandoTextCtrl does.

···

On 2/9/12 12:06 PM, luvspython wrote:

--
Robin Dunn
Software Craftsman