TreeListCtrl - resize and bgcolor

Jonatan Johansson wrote:

Hello, Happy New Year etc.!

I was looking at the TreeListCtrl demo and a few questions popped up.
I noticed it is necessary to handle window resize events and in the
event handler call the TreeListControl's SetSize method;

In the demo it is because the TreeListCtrl is located on a Panel, and the panel's EVT_SIZE handler is resizing the treelist to completly cover the panel. The treelist's EVT_SIZE is not being handled anywhere but in the treelist itself.

otherwise one
will have redrawal problems (notice how the column header changes from
http://www.cyd.liu.se/users/~jonjo002/treelistctrl/maximized.png to
http://www.cyd.liu.se/users/~jonjo002/treelistctrl/restored.png when
the window size changes). Also notice the low contrast between the
hierarchy indicating lines and the background of the TreeListCtrl.

It probably just needs a call to Refresh somewhere.

My
questions are:

* Why is it necessary to call SetSize? Shouldn't this be default
behaviour? I mean, I don't have to call SetSize explicitly for other
contorls.

It is not necessary. In the demo it is just a brute force way to not have to use a sizer.

* In the demo, self.tree.SetSize is called with self.GetSize() as the
argument (self being the panel on which the TreeListCtrl is located.
Where is the logic in setting the size of the TreeListCtrl to the size
of the panel?

It was probably done because in some situations a window derived from wx.ScrolledWindow that was placed directly in a wx.Notebook could sometimes have bg colour refresh problems on wxGTK(1). Putting a panel under the window fixes that problem.

* If I use this in the __init__ of a class derived from TreeListCtrl,
subsequent calls to the tree's GetSize method returns (150, 300),
although other values are sent as argument to SetSize in the EVT_SIZE
event handler. Why doesn't this size change?

Use what in the __init__?

* Why is the default color of the TreeListCtrl the same as the
standard panel color, rather than plain white (as is the case of
ListCtrl and TreeCtrl)?

This would be a bug. What version are you using?

* How can I change the background color to better see the hierarchy
lines? I tried using tree.SetBackgroundColour("white") but this didn't
change anything.

Also a bug. Is this a build done from CVS in the past few weeks? If so then there were some bugs dealing with background erase and colour inheritance on MSW. This would probably also explain your refresh issue above. Try updating and building again.

* After searching/reading here and there, my conclusion is that gizmos
= custom controls.
Why aren't these included in the standard wxWidgets distribution?

Because in the case of wxTreeListCtrl there is a deisre to add a new set of classes to the core that would overlap the functionality of this one. The new classes however would use a native implementaiton on at least OSX and GTK2.

For the other gizmos and contribs in general a determination is made if a class is vital or useful enough that it is worth bloating the main library to add it. If not then they end up in contrib and if people like them enough they can use them in addition to the library. There is some shift happening to this policy though, now that we have the new build system it is easy to add additional optional libs to the main build.

* How do I know what platforms this control is available on? The
gizmos don't seem to be listed at
http://www.wxwidgets.org/supported.htm. From the C++ source code and
the API reference that comes with it, it seems to be available for
Windows, Mac and GTK but I'm no C++ genius, so it would be nice to
know.

It's totally generic code, so all of them.

* Should I simply join the wxCode list and post this message there,
since most of it probably isn't wxPython-specific but rather problems
with the original C++ source?

It may or may not help as the version of the wxTreeListCtrl code I am using is a bit different than what is in wxCode. They made some changes that would have either broken the existing API or been hard to work around so I havn't updated for a while. But if my guess above is correct then the problem isn't in the wxTreeListCtrl code at all.

···

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

Jonatan Johansson wrote:

otherwise one
will have redrawal problems (notice how the column header changes from
http://www.cyd.liu.se/users/~jonjo002/treelistctrl/maximized.png to
http://www.cyd.liu.se/users/~jonjo002/treelistctrl/restored.png when
the window size changes). Also notice the low contrast between the
hierarchy indicating lines and the background of the TreeListCtrl.

It probably just needs a call to Refresh somewhere.

But you should never have to call Refresh manually to update the
visual appearance of standard controls, right? I don't call Refresh to
redraw a wx.Button, or should I do that?

No, but wxTreeListCtrl is not a standard control, it is totally generic written in wxWidgets, so there are possibly still some glitches in it. Or since it is on Windows there is possibly some clipping issues going on. If during the resize something else is temporarily overlapping the treelist then Windows may think that it has already been refreshed when it hasn't yet. It's strange but it's been known to happen. You might try adding the wx.CLIP_CHILDREN style to the parent, or the wx.CLIP_SIBLINGS style to the neighboring controls.

My
questions are:

* Why is it necessary to call SetSize? Shouldn't this be default
behaviour? I mean, I don't have to call SetSize explicitly for other
contorls.

It is not necessary. In the demo it is just a brute force way to not
have to use a sizer.

Ok. But in my code I have the TreeListCtrl added to a BoxSizer that I
later set to be the panel's sizer (using SetSizer). And I still need
to use self.tree.SetSize(self.GetSize()) for it to redraw properly.

What is self in this case? The panel? Whose EVT_SIZE is being hooked?

* In the demo, self.tree.SetSize is called with self.GetSize() as the
argument (self being the panel on which the TreeListCtrl is located.
Where is the logic in setting the size of the TreeListCtrl to the size
of the panel?

It was probably done because in some situations a window derived from
wx.ScrolledWindow that was placed directly in a wx.Notebook could
sometimes have bg colour refresh problems on wxGTK(1). Putting a panel
under the window fixes that problem.

Is backward compability with gtk1 still a goal?

Yes. But in this case it is not an uncommon thing to do anyway, regardless of platform. Putting a panel under other controls, even if none of it is visible can among other things ensures that the control is part of the tab traversal with other parts of the frame, etc. if the immediate parent would not otherwise have been a panel.

* If I use this in the __init__ of a class derived from TreeListCtrl,
subsequent calls to the tree's GetSize method returns (150, 300),
although other values are sent as argument to SetSize in the EVT_SIZE
event handler. Why doesn't this size change?

Use what in the __init__?

Oops! *JJ slaps himself in the face*
This is my TreeListCtrl class:

class MyTreeCtrl(wx.gizmos.TreeListCtrl):
    def __init__(self, parent):
        wx.gizmos.TreeListCtrl.__init__(self, parent, size = (150, 300))
                       self.AddColumn("abc")
        root = self.AddRoot("I am the root.")
        self.SetBackgroundColour("white")
                for x in range(0, 5):
            self.AppendItem(root, "sublevels")

* Why is the default color of the TreeListCtrl the same as the
standard panel color, rather than plain white (as is the case of
ListCtrl and TreeCtrl)?

This would be a bug. What version are you using?

Actually, only brand spanking new stuff.
I downloaded these three just the other day:

    wxPython 2.5.3.1
    wxPython2.5 Docs Demos and Tools
    Python 2.4

And I'm currently using these beauties on WinXP (SP2).

Okay. It looks from the screen shots that you are using the classic theme. Please try changing to the standard XP theme and run the app again and see how it compares. The classic theme is known to have some subtle little bugs that could possibly be manifesting in this way.

[...]

* After searching/reading here and there, my conclusion is that gizmos
= custom controls.
Why aren't these included in the standard wxWidgets distribution?

Because in the case of wxTreeListCtrl there is a deisre to add a new set
of classes to the core that would overlap the functionality of this one.
The new classes however would use a native implementaiton on at least
OSX and GTK2.

Native is good. Maybe cumbersome to implement, but always so much
better for the end user. It would be nice to have native multi column
ListCtrl for Windows as well; I don't know if the Windows API offers
it, but if it does, the Windows Explorer style multi colum ListCtrl
would be great. It looks good, supports ascending/descending
click-sorting of columns, auto-fit column-width and more.

We already have wx.ListCtrl which on Windows uses the same control as Explorer. See the samples in the demo. The thing that there isn't a native version of on Windows yet is the combined tree and list control that the new classes would be implementing. OSX and GTK2 have "data browser" widgets that can deal with heirarchical or tabular data, or a combination of the two, and have pluggable data models and views. If the current wxTreeListCtrl got added to the main wxWidgets lib then it would have to be maintained forever (or until 3.0, whichever comes first) and would end up being another case of similar but different functionality and all that goes along with that...

[...]

* Should I simply join the wxCode list and post this message there,
since most of it probably isn't wxPython-specific but rather problems
with the original C++ source?

It may or may not help as the version of the wxTreeListCtrl code I am
using is a bit different than what is in wxCode. They made some changes
that would have either broken the existing API or been hard to work
around so I havn't updated for a while. But if my guess above is
correct then the problem isn't in the wxTreeListCtrl code at all.

The *problems* you mean? Or what of the following do you consider is
"the way it should be"?:

* Having to call Refresh and/or SetSize to get what (IMHO) should be
default behaviour.
* Wrong default background color.
* No way to change background color.

All of the above are bugs and are something that could have been possible with the recent bugs in CVS in the core wxMSW code. Since you are not using that I'm not sure what to blame, but I have not been able to duplicate the problems in 2.5.3.1 or current CVS here. Could you send a small sample app that shows the problem so I can try it here?

Another possibility I suppose is that when I made the binaries for Python 2.4 that I didn't get all of the CVS workspace moved back to the 2.5.3.1 tag and I ended up with some code from the then current CVS... But then if I had then I shoudl be seeing the problem here as well, so it's a very slim possibility.

I'll try to get a C++ build system up and running (DevC++ or MinGW Dev
Studio with wxWidgets) so I can test and report bugs/ask questions
more accurately to the correct forum (e.g. if problems with
TreeListCtrl also occur in C++ apps, I should probably post to wxCode
list or to Otto Wyss directly, since it's not a wxPython issue).

Otto will just tell you to dump my version of wxTreeListCtrl and use the one in current wxCode, but that won't work because the Python wrappers are still expecting the former API, and some other bug fixes that Alberto or I have done to my version that havn't made it over there yet. So essentially it is a wxPython issue until I am able to sync up with the wxCode version again.

···

On Fri, 31 Dec 2004 11:12:15 -0800, Robin Dunn <robin@alldunn.com> wrote:

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

It seems that wx.FIXED_MINSIZE was causing the column header drawing
glitch all along!
Anyway, before I realized this, I converted the code to C++ and tried it out.
There were some visual differences between these apps. I took
screenshots of them first with Luna appearance (new xp look), then
with classic (but before restarting the apps - I've seen other Windows
apps that look like they should right away without restarting them
after a theme change) and then finally with classic theme after
restarting the apps.

Screenshots are here:

http://www.cyd.liu.se/users/~jonjo002/treelistctrl/cpp_python_comp_luna.png
http://www.cyd.liu.se/users/~jonjo002/treelistctrl/cpp_python_comp_classic_no_restart.png
http://www.cyd.liu.se/users/~jonjo002/treelistctrl/cpp_python_comp_classic.png

AFAIK, I've done the same stuff in both the C++ and the Python version.
(Source attached. The .cpp and .h files should be in the same folder
when compiling.)

Differences:
* Hierarchy lines clearly visible in the C++ version. So this will
probably be ok in wxPython when the TreeListCtrl in wxPython is synced
with the C++ one?
* In the C++ version, the wxNotebook isn't luna-savvy (grey tab). How come?
* TreeListCtrl sizes are different. Have I made the apps different
somewhere (where?) or do sizers work differently under wxWidgets and
wxPython?

//Jonatan

TreeListCtrl_Problem.py (1.22 KB)

treelistctrl_problem.cpp (2.53 KB)

treelistctrl.cpp (155 KB)

treelistctrl.h (20.5 KB)

Jonatan Johansson wrote:

It seems that wx.FIXED_MINSIZE was causing the column header drawing
glitch all along!

The TLC probably needs an initial size event after the columns have been added to adjust itself to their presence. Since you created the control with a size, and since the sizer would never resize it because of the flag then that didn't happen. A workaround that would let you keep the wx.FIXED_MINSIZE is to *not* set it in the base class __init__ call, but to call self.SetSize after the columns and initial items have been added.

Anyway, before I realized this, I converted the code to C++ and tried it out.
There were some visual differences between these apps. I took
screenshots of them first with Luna appearance (new xp look), then
with classic (but before restarting the apps - I've seen other Windows
apps that look like they should right away without restarting them
after a theme change) and then finally with classic theme after
restarting the apps.

Screenshots are here:

http://www.cyd.liu.se/users/~jonjo002/treelistctrl/cpp_python_comp_luna.png
http://www.cyd.liu.se/users/~jonjo002/treelistctrl/cpp_python_comp_classic_no_restart.png
http://www.cyd.liu.se/users/~jonjo002/treelistctrl/cpp_python_comp_classic.png

AFAIK, I've done the same stuff in both the C++ and the Python version.
(Source attached. The .cpp and .h files should be in the same folder
when compiling.)

Differences:
* Hierarchy lines clearly visible in the C++ version. So this will
probably be ok in wxPython when the TreeListCtrl in wxPython is synced
with the C++ one?

Yep. Probably just a different pen being used to draw the lines.

* In the C++ version, the wxNotebook isn't luna-savvy (grey tab). How come?

You probably didn't have the manifest file (or resource) that tells XP to use the themed version of the common controls DLL.

* TreeListCtrl sizes are different. Have I made the apps different
somewhere (where?) or do sizers work differently under wxWidgets and
wxPython?

The two versions of TLC probably have different implementations of the DoGetBestSize method. This method is part of what the sizers use to determine what the minimum size of widgets should be when they calculate the layout. If they are not going to be stretching the item for whatever reason then it falls back to the min size, and if a min size has not explicitly been set then it uses the best size.

···

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

The TLC probably needs an initial size event after the columns have been
added to adjust itself to their presence. Since you created the control
with a size, and since the sizer would never resize it because of the
flag then that didn't happen. A workaround that would let you keep the
wx.FIXED_MINSIZE is to *not* set it in the base class __init__ call, but
to call self.SetSize after the columns and initial items have been added.

You are right -- SetSize did the job!
Still, this renders the size constructor parameter useless, since you
will always have to call AddColumn to make use of the TreeListCtrl. So
these necessary size recalculations should probably be taken care of
in AddColumn automatically.
Anyway, this is a bug in the original C++ implementation, not wxPython.

> * In the C++ version, the wxNotebook isn't luna-savvy (grey tab). How come?

You probably didn't have the manifest file (or resource) that tells XP
to use the themed version of the common controls DLL.

I'm puzzled. I thought wxPython (most of the time) was just a Python
<--> C++ bridge, meaning it would use the same stuff (widgets in this
case :)) as wxWidgets. But the wxNotebook control looks luna-savvy in
wxPython! How come?

Also, what is this manifest/resource thing? Something to do with my
C++ environment? (if so, I guess this answers the "How come?"-question
above) How do I fix it?

//Jonatan

···

On Sat, 01 Jan 2005 18:44:21 -0800, Robin Dunn <robin@alldunn.com> wrote:

Jonatan Johansson wrote:

The TLC probably needs an initial size event after the columns have been
added to adjust itself to their presence. Since you created the control
with a size, and since the sizer would never resize it because of the
flag then that didn't happen. A workaround that would let you keep the
wx.FIXED_MINSIZE is to *not* set it in the base class __init__ call, but
to call self.SetSize after the columns and initial items have been added.
   
You are right -- SetSize did the job!
Still, this renders the size constructor parameter useless, since you
will always have to call AddColumn to make use of the TreeListCtrl. So
these necessary size recalculations should probably be taken care of
in AddColumn automatically.
Anyway, this is a bug in the original C++ implementation, not wxPython.

* In the C++ version, the wxNotebook isn't luna-savvy (grey tab). How come?
     

You probably didn't have the manifest file (or resource) that tells XP
to use the themed version of the common controls DLL.
   
I'm puzzled. I thought wxPython (most of the time) was just a Python
<--> C++ bridge, meaning it would use the same stuff (widgets in this
case :)) as wxWidgets. But the wxNotebook control looks luna-savvy in
wxPython! How come?

Because "python.exe.manifest" is present in the python folder.

Also, what is this manifest/resource thing? Something to do with my
C++ environment? (if so, I guess this answers the "How come?"-question
above) How do I fix it?

Just copy "python.exe.manifest" to the folder where your C++ version exe sits and name it "yourexe.exe.manifest".

See you
Werner

···

On Sat, 01 Jan 2005 18:44:21 -0800, Robin Dunn <robin@alldunn.com> wrote:

//Jonatan

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

>Also, what is this manifest/resource thing? Something to do with my
>C++ environment? (if so, I guess this answers the "How come?"-question
>above) How do I fix it?

Just copy "python.exe.manifest" to the folder where your C++ version exe
sits and name it "yourexe.exe.manifest".

Works like a charm!
(BTW, I later found more details of the manifest-thingy at
http://www.wxwindows.org/faqmsw.htm#winxp, in case any one is
interested)

See you
Werner

Thanks!

//Jonatan

But...but...the .cpp source at wxcode.sf.net doesn't even have this
change! Robin's Time Machine??

In that case: cool :wink:

//Jonatan

···

On Mon, 03 Jan 2005 11:00:23 -0800, Robin Dunn <robin@alldunn.com> wrote:

> You are right -- SetSize did the job!
> Still, this renders the size constructor parameter useless, since you
> will always have to call AddColumn to make use of the TreeListCtrl. So
> these necessary size recalculations should probably be taken care of
> in AddColumn automatically.

Yep, I've already changed that.

Jonatan Johansson wrote:

···

On Mon, 03 Jan 2005 11:00:23 -0800, Robin Dunn <robin@alldunn.com> wrote:

You are right -- SetSize did the job!
Still, this renders the size constructor parameter useless, since you
will always have to call AddColumn to make use of the TreeListCtrl. So
these necessary size recalculations should probably be taken care of
in AddColumn automatically.

Yep, I've already changed that.

But...but...the .cpp source at wxcode.sf.net doesn't even have this
change! Robin's Time Machine??

No, I meant that I had already made the change to the wxPython version of wxTreeListCtrl. I did it on Saturday but it didn't get checked in until this morning.

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