]> git.saurik.com Git - wxWidgets.git/commitdiff
Applied Greg's patch to tree control and related.
authorRobert Roebling <robert@roebling.de>
Sat, 18 Aug 2001 13:09:26 +0000 (13:09 +0000)
committerRobert Roebling <robert@roebling.de>
Sat, 18 Aug 2001 13:09:26 +0000 (13:09 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11404 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

12 files changed:
include/wx/defs.h
include/wx/generic/treectlg.h
include/wx/treebase.h
include/wx/treectrl.h
samples/treectrl/treectrl.cpp
samples/treectrl/treectrl.h
src/common/resource.cpp
src/common/treebase.cpp
src/generic/dirctrlg.cpp
src/generic/dirdlgg.cpp
src/generic/treectlg.cpp
src/html/helpfrm.cpp

index 8cb02a12d82a446f5d4fe9ed5ce6f40c922512ae..4f9855a832e1a397a2b0982936b326307c95368c 100644 (file)
@@ -1170,21 +1170,6 @@ enum wxBorder
 #define wxSB_HORIZONTAL      wxHORIZONTAL
 #define wxSB_VERTICAL        wxVERTICAL
 
-/*
- * wxTreeCtrl flags
- */
-#define wxTR_HAS_BUTTONS     0x0004
-#define wxTR_EDIT_LABELS     0x0008
-#define wxTR_LINES_AT_ROOT   0x0010
-
-#define wxTR_SINGLE          0x0000
-#define wxTR_MULTIPLE        0x0020
-#define wxTR_EXTENDED        0x0040
-#define wxTR_HAS_VARIABLE_ROW_HEIGHT 0x0080
-#define wxTR_NO_LINES        0x0100
-#define wxTR_MAC_BUTTONS     0x0200
-#define wxTR_ROW_LINES       0x0400
-
 /*
  * wxSpinButton flags.
  * Note that a wxSpinCtrl is sometimes defined as
index 7958708b1e97333921040f70069865d8c333129b..a330263f1db71a23fba7a8660b46590abc349230 100644 (file)
 
 #if wxUSE_TREECTRL
 
-#include "wx/defs.h"
-#include "wx/string.h"
-#include "wx/object.h"
-#include "wx/event.h"
 #include "wx/scrolwin.h"
-#include "wx/textctrl.h"
 #include "wx/pen.h"
-#include "wx/dynarray.h"
-#include "wx/timer.h"
-#include "wx/treebase.h"
 
 // -----------------------------------------------------------------------------
 // forward declaration
@@ -55,11 +47,7 @@ public:
     wxGenericTreeCtrl(wxWindow *parent, wxWindowID id = -1,
                const wxPoint& pos = wxDefaultPosition,
                const wxSize& size = wxDefaultSize,
-#ifdef __WXMAC__
-               long style = wxTR_MAC_BUTTONS | wxTR_NO_LINES | wxTR_ROW_LINES,
-#else
-               long style = wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT,
-#endif
+               long style = wxTR_DEFAULT_STYLE,
                const wxValidator &validator = wxDefaultValidator,
                const wxString& name = wxTreeCtrlNameStr)
     {
@@ -72,11 +60,7 @@ public:
     bool Create(wxWindow *parent, wxWindowID id = -1,
                 const wxPoint& pos = wxDefaultPosition,
                 const wxSize& size = wxDefaultSize,
-#ifdef __WXMAC__
-               long style = wxTR_MAC_BUTTONS | wxTR_NO_LINES | wxTR_ROW_LINES,
-#else
-               long style = wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT,
-#endif
+                long style = wxTR_DEFAULT_STYLE,
                 const wxValidator &validator = wxDefaultValidator,
                 const wxString& name = wxTreeCtrlNameStr);
 
@@ -110,18 +94,21 @@ public:
         // checked/unchecked) which are taken from the state image list.
     wxImageList *GetImageList() const;
     wxImageList *GetStateImageList() const;
+    wxImageList *GetButtonsImageList() const;
 
     void SetImageList(wxImageList *imageList);
     void SetStateImageList(wxImageList *imageList);
+    void SetButtonsImageList(wxImageList *imageList);
     void AssignImageList(wxImageList *imageList);
     void AssignStateImageList(wxImageList *imageList);
+    void AssignButtonsImageList(wxImageList *imageList);
 
     // Functions to work with tree ctrl items.
 
     // accessors
     // ---------
 
-        // retrieve items label
+        // retrieve item's label
     wxString GetItemText(const wxTreeItemId& item) const;
         // get one of the images associated with the item (normal by default)
     int GetItemImage(const wxTreeItemId& item,
@@ -132,7 +119,7 @@ public:
     // modifiers
     // ---------
 
-        // set items label
+        // set item's label
     void SetItemText(const wxTreeItemId& item, const wxString& text);
         // get one of the images associated with the item (normal by default)
     void SetItemImage(const wxTreeItemId& item, int image,
@@ -149,18 +136,22 @@ public:
         // the item will be shown in bold
     void SetItemBold(const wxTreeItemId& item, bool bold = TRUE);
 
-        // set the items text colour
+        // set the item's text colour
     void SetItemTextColour(const wxTreeItemId& item, const wxColour& col);
 
-        // set the items background colour
+        // set the item's background colour
     void SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& col);
 
-        // set the items font (should be of the same height for all items)
+        // set the item's font (should be of the same height for all items)
     void SetItemFont(const wxTreeItemId& item, const wxFont& font);
 
         // set the window font
     virtual bool SetFont( const wxFont &font );
 
+       // set the styles.  No need to specify a GetWindowStyle here since
+       // the base wxWindow member function will do it for us
+    void SetWindowStyle(const long styles);
+
     // item status inquiries
     // ---------------------
 
@@ -176,6 +167,7 @@ public:
     bool IsSelected(const wxTreeItemId& item) const;
         // is item text in bold font?
     bool IsBold(const wxTreeItemId& item) const;
+        // does the layout include space for a button?
 
     // number of children
     // ------------------
@@ -296,6 +288,7 @@ public:
     void EnsureVisible(const wxTreeItemId& item);
         // scroll to this item (but don't expand its parent)
     void ScrollTo(const wxTreeItemId& item);
+    void AdjustMyScrollbars();
 
         // The first function is more portable (because easier to implement
         // on other platforms), but the second one returns some extra info.
@@ -360,29 +353,30 @@ protected:
 
     wxGenericTreeItem   *m_anchor;
     wxGenericTreeItem   *m_current, *m_key_current, *m_currentEdit;
-    bool                 m_hasFocus;
-    bool                 m_dirty;
-    int                  m_xScroll,m_yScroll;
-    unsigned int         m_indent;
-    unsigned int         m_spacing;
+    unsigned short       m_indent;
+    unsigned short       m_spacing;
     int                  m_lineHeight;
     wxPen                m_dottedPen;
     wxBrush             *m_hilightBrush;
-    wxImageList         *m_imageListNormal,
-                        *m_imageListState;
+    bool                 m_hasFocus;
+    bool                 m_dirty;
     bool                 m_ownsImageListNormal, 
-                         m_ownsImageListState;
+                         m_ownsImageListState,
+                         m_ownsImageListButtons;
+    bool                 m_isDragging; // true between BEGIN/END drag events
+    bool                 m_renameAccept;
+    bool                 m_lastOnSame;  // last click on the same item as prev
+    wxImageList         *m_imageListNormal,
+                        *m_imageListState,
+                        *m_imageListButtons;
 
     int                  m_dragCount;
     wxPoint              m_dragStart;
-    bool                 m_isDragging; // true between BEGIN/END drag events
     wxGenericTreeItem   *m_dropTarget;
     wxCursor             m_oldCursor;  // cursor is changed while dragging
     wxGenericTreeItem   *m_oldSelection;
 
     wxTimer             *m_renameTimer;
-    bool                 m_renameAccept;
-    bool                 m_lastOnSame;  // last click on the same item as prev
     wxString             m_renameRes;
 
     // the common part of all ctors
@@ -394,10 +388,12 @@ protected:
                               const wxString& text,
                               int image, int selectedImage,
                               wxTreeItemData *data);
+    bool HasButtons(void) const
+        { return (m_imageListButtons != NULL)
+              || HasFlag(wxTR_TWIST_BUTTONS|wxTR_HAS_BUTTONS); }
 
-public:
-    void AdjustMyScrollbars();
 protected:
+    void CalculateLineHeight();
     int  GetLineHeight(wxGenericTreeItem *item) const;
     void PaintLevel( wxGenericTreeItem *item, wxDC& dc, int level, int &y );
     void PaintItem( wxGenericTreeItem *item, wxDC& dc);
@@ -433,24 +429,22 @@ private:
 
 class WXDLLEXPORT wxTreeCtrl: public wxGenericTreeCtrl
 {
-public:
     DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
 
+public:
     wxTreeCtrl() {}
 
     wxTreeCtrl(wxWindow *parent, wxWindowID id = -1,
                const wxPoint& pos = wxDefaultPosition,
                const wxSize& size = wxDefaultSize,
-               long style = wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT,
+               long style = wxTR_DEFAULT_STYLE,
                const wxValidator &validator = wxDefaultValidator,
                const wxString& name = wxTreeCtrlNameStr)
+    : wxGenericTreeCtrl(parent, id, pos, size, style, validator, name)
     {
-        Create(parent, id, pos, size, style, validator, name);
     }
-
 };
-
-#endif
+#endif // !__WXMSW__ || __WIN16__ || __WXUNIVERSAL__
 
 #endif // wxUSE_TREECTRL
 
index 8d62734468d329b03a3e80f708f87f88ca6c221e..1d91001888d07243c0dc0ac8a429c7c9766f6459 100644 (file)
@@ -22,7 +22,7 @@
 
 #if wxUSE_TREECTRL
 
-#include "wx/control.h"
+#include "wx/window.h"  // for wxClientData
 #include "wx/event.h"
 
 // ----------------------------------------------------------------------------
@@ -110,6 +110,40 @@ enum wxTreeItemIcon
     wxTreeItemIcon_Max
 };
 
+enum wxButtonImage              // effectively the same as wxTreeItemIcon
+{
+    wxCLOSED_BUTTON = 0,                // closed, not selected
+    wxCLOSED_BUTTON_SELECTED,           // closed,     selected
+    wxOPEN_BUTTON,                      // open,   not selected
+    wxOPEN_BUTTON_SELECTED              // open,       selected
+};
+
+/*
+ * wxTreeCtrl flags
+ */
+// TODO: maybe renumber these?
+#define wxTR_NO_BUTTONS      0x0000     // for convenience
+#define wxTR_HAS_BUTTONS     0x0004     // generates a +/- button
+#define wxTR_TWIST_BUTTONS   0x0008     // twister buttons
+#define wxTR_NO_LINES        0x0100     // don't generate level connectors
+#define wxTR_MAC_BUTTONS     wxTR_TWIST_BUTTONS  // backward compatibility
+
+#define wxTR_SINGLE          0x0000     // for convenience
+#define wxTR_MULTIPLE        0x0020     // can select multiple items
+#define wxTR_EXTENDED        0x0040     // TODO: allow extended selection
+
+#define wxTR_EDIT_LABELS     0x0200     // can edit item labels
+#define wxTR_LINES_AT_ROOT   0x0010     // specific to wxMSW
+#define wxTR_HIDE_ROOT       0x0800     // don't display root node
+#define wxTR_ROW_LINES       0x0400     // put border around items
+#define wxTR_HAS_VARIABLE_ROW_HEIGHT 0x0080 // what it says
+
+// TODO: different default styles for wxGTK, wxMotif, whatever?
+#ifdef __WXMAC__
+    #define wxTR_DEFAULT_STYLE (wxTR_TWIST_BUTTONS|wxTR_NO_LINES|wxTR_ROW_LINES)
+#else
+    #define wxTR_DEFAULT_STYLE (wxTR_HAS_BUTTONS|wxTR_LINES_AT_ROOT)
+#endif
 
 // values for the `flags' parameter of wxTreeCtrl::HitTest() which determine
 // where exactly the specified point is situated:
@@ -220,8 +254,6 @@ private:
                   m_itemOld;
     wxPoint       m_pointDrag;
     wxString      m_label;
-
-    DECLARE_DYNAMIC_CLASS(wxTreeEvent)
 };
 
 typedef void (wxEvtHandler::*wxTreeEventFunction)(wxTreeEvent&);
@@ -303,6 +335,5 @@ END_DECLARE_EVENT_TYPES()
 
 #endif // wxUSE_TREECTRL
 
-#endif
-    // _WX_TREEBASE_H_
+#endif // _WX_TREEBASE_H_
 
index 08e0e15973dda987c53ce3e6d4fa8d4708c3f3a9..4c720bb17f40c4e4267683621d2bb275b674f156 100644 (file)
@@ -36,7 +36,5 @@
 #endif
 */
 
-#endif
-    // _WX_TREECTRL_H_BASE_
-
+#endif // _WX_TREECTRL_H_BASE_
 
index 749bc0d3c9251a9daa3f8e62275b9e95607a533d..9c7c1c0d637fbb0a18f538d52d440dfbd446ce6b 100644 (file)
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_SIZE(MyFrame::OnSize)
 
-    EVT_MENU(TreeTest_Quit, MyFrame::OnQuit)
-    EVT_MENU(TreeTest_About, MyFrame::OnAbout)
-    EVT_MENU(TreeTest_Dump, MyFrame::OnDump)
+#define MENU_LINK(name) EVT_MENU(TreeTest_##name, MyFrame::On##name)
+    MENU_LINK(Quit)
+    MENU_LINK(About)
+    MENU_LINK(TogButtons)
+    MENU_LINK(TogTwist)
+    MENU_LINK(TogLines)
+    MENU_LINK(TogEdit)
+    MENU_LINK(TogHideRoot)
+    MENU_LINK(TogRootLines)
+    MENU_LINK(TogBorder)
+    MENU_LINK(Dump)
 #ifndef NO_MULTIPLE_SELECTION
-    EVT_MENU(TreeTest_DumpSelected, MyFrame::OnDumpSelected)
-    EVT_MENU(TreeTest_Select, MyFrame::OnSelect)
-    EVT_MENU(TreeTest_Unselect, MyFrame::OnUnselect)
-    EVT_MENU(TreeTest_ToggleSel, MyFrame::OnToggleSel)
+    MENU_LINK(DumpSelected)
+    MENU_LINK(Select)
+    MENU_LINK(Unselect)
+    MENU_LINK(ToggleSel)
 #endif // NO_MULTIPLE_SELECTION
-    EVT_MENU(TreeTest_Rename, MyFrame::OnRename)
-    EVT_MENU(TreeTest_Count, MyFrame::OnCount)
-    EVT_MENU(TreeTest_CountRec, MyFrame::OnCountRec)
-    EVT_MENU(TreeTest_Sort, MyFrame::OnSort)
-    EVT_MENU(TreeTest_SortRev, MyFrame::OnSortRev)
-    EVT_MENU(TreeTest_Bold, MyFrame::OnSetBold)
-    EVT_MENU(TreeTest_UnBold, MyFrame::OnClearBold)
-    EVT_MENU(TreeTest_Delete, MyFrame::OnDelete)
-    EVT_MENU(TreeTest_DeleteChildren, MyFrame::OnDeleteChildren)
-    EVT_MENU(TreeTest_DeleteAll, MyFrame::OnDeleteAll)
-    EVT_MENU(TreeTest_Recreate, MyFrame::OnRecreate)
-    EVT_MENU(TreeTest_ToggleImages, MyFrame::OnToggleImages)
-    EVT_MENU(TreeTest_SetImageSize, MyFrame::OnSetImageSize)
-    EVT_MENU(TreeTest_CollapseAndReset, MyFrame::OnCollapseAndReset)
-    EVT_MENU(TreeTest_EnsureVisible, MyFrame::OnEnsureVisible)
-    EVT_MENU(TreeTest_AddItem, MyFrame::OnAddItem)
-    EVT_MENU(TreeTest_InsertItem, MyFrame::OnInsertItem)
-    EVT_MENU(TreeTest_IncIndent, MyFrame::OnIncIndent)
-    EVT_MENU(TreeTest_DecIndent, MyFrame::OnDecIndent)
-    EVT_MENU(TreeTest_IncSpacing, MyFrame::OnIncSpacing)
-    EVT_MENU(TreeTest_DecSpacing, MyFrame::OnDecSpacing)
-    EVT_MENU(TreeTest_ToggleIcon, MyFrame::OnToggleIcon)
+    MENU_LINK(Rename)
+    MENU_LINK(Count)
+    MENU_LINK(CountRec)
+    MENU_LINK(Sort)
+    MENU_LINK(SortRev)
+    MENU_LINK(SetBold)
+    MENU_LINK(ClearBold)
+    MENU_LINK(Delete)
+    MENU_LINK(DeleteChildren)
+    MENU_LINK(DeleteAll)
+    MENU_LINK(Recreate)
+    MENU_LINK(ToggleImages)
+    MENU_LINK(ToggleButtons)
+    MENU_LINK(SetImageSize)
+    MENU_LINK(CollapseAndReset)
+    MENU_LINK(EnsureVisible)
+    MENU_LINK(AddItem)
+    MENU_LINK(InsertItem)
+    MENU_LINK(IncIndent)
+    MENU_LINK(DecIndent)
+    MENU_LINK(IncSpacing)
+    MENU_LINK(DecSpacing)
+    MENU_LINK(ToggleIcon)
+#undef MENU_LINK
+
 END_EVENT_TABLE()
 
 #if USE_GENERIC_TREECTRL
@@ -158,6 +169,7 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
 #if wxUSE_MENUS
     // Make a menubar
     wxMenu *file_menu = new wxMenu,
+           *style_menu = new wxMenu,
            *tree_menu = new wxMenu,
            *item_menu = new wxMenu;
 
@@ -165,11 +177,21 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
     file_menu->AppendSeparator();
     file_menu->Append(TreeTest_Quit, "E&xit\tAlt-X");
 
+    style_menu->Append(TreeTest_TogButtons, "Toggle &normal buttons");
+    style_menu->Append(TreeTest_TogTwist, "Toggle &twister buttons");
+    style_menu->Append(TreeTest_ToggleButtons, "Toggle image &buttons");
+    style_menu->AppendSeparator();
+    style_menu->Append(TreeTest_TogLines, "Toggle &connecting lines");
+    style_menu->Append(TreeTest_TogRootLines, "Toggle &lines at root");
+    style_menu->Append(TreeTest_TogHideRoot, "Toggle &hidden root");
+    style_menu->Append(TreeTest_TogBorder, "Toggle &item border");
+    style_menu->Append(TreeTest_TogEdit, "Toggle &edit mode");
 #ifndef NO_MULTIPLE_SELECTION
-    tree_menu->Append(TreeTest_ToggleSel, "&Toggle selection mode");
+    style_menu->Append(TreeTest_ToggleSel, "Toggle &selection mode");
 #endif // NO_MULTIPLE_SELECTION
-    tree_menu->Append(TreeTest_ToggleImages, "&Show images", "", TRUE);
-    tree_menu->Append(TreeTest_SetImageSize, "Set image si&ze...");
+    style_menu->Append(TreeTest_ToggleImages, "Toggle show ima&ges");
+    style_menu->Append(TreeTest_SetImageSize, "Set image si&ze...");
+
     tree_menu->Append(TreeTest_Recreate, "&Recreate the tree");
     tree_menu->Append(TreeTest_CollapseAndReset, "C&ollapse and reset");
     tree_menu->AppendSeparator();
@@ -197,10 +219,10 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
     item_menu->Append(TreeTest_Rename, "&Rename item...");
 
     item_menu->AppendSeparator();
-    item_menu->Append(TreeTest_Bold, "Make item &bold");
-    item_menu->Append(TreeTest_UnBold, "Make item &not bold");
+    item_menu->Append(TreeTest_SetBold, "Make item &bold");
+    item_menu->Append(TreeTest_ClearBold, "Make item &not bold");
     item_menu->AppendSeparator();
-    item_menu->Append(TreeTest_ToggleIcon, "Toggle the items &icon");
+    item_menu->Append(TreeTest_ToggleIcon, "Toggle the item's &icon");
 
 #ifndef NO_MULTIPLE_SELECTION
     item_menu->AppendSeparator();
@@ -211,16 +233,17 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
 
     wxMenuBar *menu_bar = new wxMenuBar;
     menu_bar->Append(file_menu, "&File");
+    menu_bar->Append(style_menu, "&Style");
     menu_bar->Append(tree_menu, "&Tree");
     menu_bar->Append(item_menu, "&Item");
     SetMenuBar(menu_bar);
 
-    menu_bar->Check(TreeTest_ToggleImages, TRUE);
+    //menu_bar->Check(TreeTest_ToggleImages, TRUE);
 #endif // wxUSE_MENUS
 
     m_treeCtrl = new MyTreeCtrl(this, TreeTest_Ctrl,
                                 wxDefaultPosition, wxDefaultSize,
-                                wxTR_MAC_BUTTONS | wxTR_NO_LINES |
+                                wxTR_TWIST_BUTTONS | wxTR_NO_LINES |
                                 wxTR_EDIT_LABELS |
 #ifndef NO_VARIABLE_HEIGHT
                                 wxTR_HAS_VARIABLE_ROW_HEIGHT |
@@ -253,6 +276,11 @@ MyFrame::~MyFrame()
     delete wxLog::SetActiveTarget(NULL);
 }
 
+void MyFrame::TogStyle(long flag)
+{
+        m_treeCtrl->SetWindowStyle(m_treeCtrl->GetWindowStyle() ^ flag);
+}
+
 void MyFrame::OnSize(wxSizeEvent& event)
 {
     if ( m_treeCtrl && m_textCtrl )
@@ -347,6 +375,8 @@ void MyFrame::OnDump(wxCommandEvent& WXUNUSED(event))
 
 void MyFrame::OnToggleSel(wxCommandEvent& WXUNUSED(event))
 {
+    TogStyle(wxTR_MULTIPLE);
+#if 0
     long style = m_treeCtrl->GetWindowStyle();
     if ( style & wxTR_MULTIPLE )
         style &= ~wxTR_MULTIPLE;
@@ -359,6 +389,7 @@ void MyFrame::OnToggleSel(wxCommandEvent& WXUNUSED(event))
                                 wxDefaultPosition, wxDefaultSize,
                                 style);
     Resize(GetClientSize());
+#endif
 }
 
 void MyFrame::OnDumpSelected(wxCommandEvent& WXUNUSED(event))
@@ -421,21 +452,20 @@ void MyFrame::OnDeleteAll(wxCommandEvent& WXUNUSED(event))
 void MyFrame::OnRecreate(wxCommandEvent& event)
 {
     OnDeleteAll(event);
-    m_treeCtrl->AddTestItemsToTree(3, 2);
+    m_treeCtrl->AddTestItemsToTree(5, 2);
 }
 
 void MyFrame::OnSetImageSize(wxCommandEvent& event)
 {
-    long size = wxGetNumberFromUser("Enter the size for the images to use",
+    int size = wxGetNumberFromUser("Enter the size for the images to use",
                                     "Size: ",
                                     "TreeCtrl sample",
-                                    16);
+                                    m_treeCtrl->ImageSize());
     if ( size == -1 )
         return;
 
-    m_treeCtrl->CreateImageList((int)size);
-
-    OnRecreate(event);
+    m_treeCtrl->CreateImageList(size);
+    wxGetApp().SetShowImages(TRUE);
 }
 
 void MyFrame::OnToggleImages(wxCommandEvent& event)
@@ -443,17 +473,27 @@ void MyFrame::OnToggleImages(wxCommandEvent& event)
     if ( wxGetApp().ShowImages() )
     {
         m_treeCtrl->CreateImageList(-1);
-
         wxGetApp().SetShowImages(FALSE);
     }
     else
     {
-        m_treeCtrl->CreateImageList();
-
+        m_treeCtrl->CreateImageList(0);
         wxGetApp().SetShowImages(TRUE);
     }
+}
 
-    OnRecreate(event);
+void MyFrame::OnToggleButtons(wxCommandEvent& event)
+{
+    if ( wxGetApp().ShowButtons() )
+    {
+        m_treeCtrl->CreateButtonsImageList(-1);
+        wxGetApp().SetShowButtons(FALSE);
+    }
+    else
+    {
+        m_treeCtrl->CreateButtonsImageList(15);
+        wxGetApp().SetShowButtons(TRUE);
+    }
 }
 
 void MyFrame::OnCollapseAndReset(wxCommandEvent& event)
@@ -534,64 +574,108 @@ MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
           : wxTreeCtrl(parent, id, pos, size, style)
 {
     m_reverseSort = FALSE;
-    m_imageListNormal = NULL;
 
     CreateImageList();
 
     // Add some items to the tree
-    AddTestItemsToTree(3, 2);
+    AddTestItemsToTree(5, 2);
 }
 
 void MyTreeCtrl::CreateImageList(int size)
 {
-    delete m_imageListNormal;
-
     if ( size == -1 )
     {
-        m_imageListNormal = NULL;
+        SetImageList(NULL);
+        return;
     }
+    if ( size == 0 )
+        size = m_imageSize;
     else
-    {
-        // Make an image list containing small icons
-        m_imageListNormal = new wxImageList(size, size, TRUE);
+        m_imageSize = size;
+
+    // Make an image list containing small icons
+    wxImageList *images = new wxImageList(size, size, TRUE);
 
-        // should correspond to TreeCtrlIcon_xxx enum
+    // should correspond to TreeCtrlIcon_xxx enum
 #if defined(__WXMSW__) && defined(__WIN16__)
-        m_imageListNormal->Add(wxBitmap("bitmap1", wxBITMAP_TYPE_BMP_RESOURCE));
-        m_imageListNormal->Add(wxBitmap("bitmap2", wxBITMAP_TYPE_BMP_RESOURCE));
-        m_imageListNormal->Add(wxBitmap("bitmap3", wxBITMAP_TYPE_BMP_RESOURCE));
-        m_imageListNormal->Add(wxBitmap("bitmap4", wxBITMAP_TYPE_BMP_RESOURCE));
-        m_imageListNormal->Add(wxBitmap("bitmap5", wxBITMAP_TYPE_BMP_RESOURCE));
+    images->Add(wxBitmap("bitmap1", wxBITMAP_TYPE_BMP_RESOURCE));
+    images->Add(wxBitmap("bitmap2", wxBITMAP_TYPE_BMP_RESOURCE));
+    images->Add(wxBitmap("bitmap3", wxBITMAP_TYPE_BMP_RESOURCE));
+    images->Add(wxBitmap("bitmap4", wxBITMAP_TYPE_BMP_RESOURCE));
+    images->Add(wxBitmap("bitmap5", wxBITMAP_TYPE_BMP_RESOURCE));
 #else // !MSW
-        wxIcon icons[5];
-        icons[0] = wxICON(icon1);
-        icons[1] = wxICON(icon2);
-        icons[2] = wxICON(icon3);
-        icons[3] = wxICON(icon4);
-        icons[4] = wxICON(icon5);
-
-        int sizeOrig = icons[0].GetWidth();
-        for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
+    wxBusyCursor wait;
+    wxIcon icons[5];
+    icons[0] = wxICON(icon1);
+    icons[1] = wxICON(icon2);
+    icons[2] = wxICON(icon3);
+    icons[3] = wxICON(icon4);
+    icons[4] = wxICON(icon5);
+
+    int sizeOrig = icons[0].GetWidth();
+    for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
+    {
+        if ( size == sizeOrig )
         {
-            if ( size == sizeOrig )
-            {
-                m_imageListNormal->Add(icons[i]);
-            }
-            else
-            {
-                m_imageListNormal->Add(wxImage(icons[i]).Rescale(size, size).
-                                        ConvertToBitmap());
-            }
+            images->Add(icons[i]);
         }
+        else
+        {
+            images->Add(wxImage(icons[i]).Rescale(size, size).
+                                    ConvertToBitmap());
+        }
+    }
 #endif // MSW/!MSW
+
+    AssignImageList(images);
+}
+
+void MyTreeCtrl::CreateButtonsImageList(int size)
+{
+    if ( size == -1 )
+    {
+        SetButtonsImageList(NULL);
+        return;
+    }
+
+    // Make an image list containing small icons
+    wxImageList *images = new wxImageList(size, size, TRUE);
+
+    // should correspond to TreeCtrlIcon_xxx enum
+#if defined(__WXMSW__) && defined(__WIN16__)
+    images->Add(wxBitmap("bitmap1", wxBITMAP_TYPE_BMP_RESOURCE));
+    images->Add(wxBitmap("bitmap2", wxBITMAP_TYPE_BMP_RESOURCE));
+    images->Add(wxBitmap("bitmap3", wxBITMAP_TYPE_BMP_RESOURCE));
+    images->Add(wxBitmap("bitmap4", wxBITMAP_TYPE_BMP_RESOURCE));
+    images->Add(wxBitmap("bitmap5", wxBITMAP_TYPE_BMP_RESOURCE));
+#else // !MSW
+    wxBusyCursor wait;
+    wxIcon icons[4];
+    icons[0] = wxICON(icon3);   // closed
+    icons[1] = wxICON(icon3);   // closed, selected
+    icons[2] = wxICON(icon5);   // open
+    icons[3] = wxICON(icon5);   // open, selected
+
+    for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
+    {
+        int sizeOrig = icons[i].GetWidth();
+        if ( size == sizeOrig )
+        {
+            images->Add(icons[i]);
+        }
+        else
+        {
+            images->Add(wxImage(icons[i]).Rescale(size, size).
+                                    ConvertToBitmap());
+        }
     }
+#endif // MSW/!MSW
 
-    SetImageList(m_imageListNormal);
+    AssignButtonsImageList(images);
 }
 
 MyTreeCtrl::~MyTreeCtrl()
 {
-    delete m_imageListNormal;
 }
 
 int MyTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
@@ -795,7 +879,7 @@ void MyTreeCtrl::OnBeginLabelEdit(wxTreeEvent& event)
 {
     wxLogMessage("OnBeginLabelEdit");
 
-    // for testing, prevent this items label editing
+    // for testing, prevent this item's label editing
     wxTreeItemId itemId = event.GetItem();
     if ( IsTestItem(itemId) )
     {
index 3f89a7206487f84d9c1828f83eab3f9d29368ca6..98913159683b57717451aaea12adb3bc714945af 100644 (file)
 class MyApp : public wxApp
 {
 public:
-    MyApp() { m_showImages = TRUE; }
+    MyApp() { m_showImages = TRUE; m_showButtons = FALSE; }
 
     bool OnInit();
 
     void SetShowImages(bool show) { m_showImages = show; }
     bool ShowImages() const { return m_showImages; }
 
+    void SetShowButtons(bool show) { m_showButtons = show; }
+    bool ShowButtons() const { return m_showButtons; }
+
 private:
-    bool m_showImages;
+    bool m_showImages, m_showButtons;
 };
 
 class MyTreeItemData : public wxTreeItemData
@@ -88,6 +91,7 @@ public:
     void GetItemsRecursively(const wxTreeItemId& idParent, long cookie);
 
     void CreateImageList(int size = 16);
+    void CreateButtonsImageList(int size = 11);
 
     void AddTestItemsToTree(size_t numChildren, size_t depth);
 
@@ -99,6 +103,8 @@ public:
 
     void ShowMenu(wxTreeItemId id, const wxPoint& pt);
 
+    int ImageSize(void) const { return m_imageSize; }
+
 protected:
     virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);
 
@@ -115,7 +121,7 @@ private:
                              size_t depth,
                              size_t folder);
 
-    wxImageList *m_imageListNormal;
+    int          m_imageSize;               // current size of images
     bool         m_reverseSort;             // flag for OnCompareItems
     wxTreeItemId m_lastItem,                // for OnEnsureVisible()
                  m_draggedItem;             // item being dragged right now
@@ -140,6 +146,14 @@ public:
     void OnQuit(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
 
+    void OnTogButtons(wxCommandEvent& event)   { TogStyle(wxTR_HAS_BUTTONS); }
+    void OnTogTwist(wxCommandEvent& event)     { TogStyle(wxTR_TWIST_BUTTONS); }
+    void OnTogLines(wxCommandEvent& event)     { TogStyle(wxTR_NO_LINES); }
+    void OnTogEdit(wxCommandEvent& event)      { TogStyle(wxTR_EDIT_LABELS); }
+    void OnTogHideRoot(wxCommandEvent& event)  { TogStyle(wxTR_HIDE_ROOT); }
+    void OnTogRootLines(wxCommandEvent& event) { TogStyle(wxTR_LINES_AT_ROOT); }
+    void OnTogBorder(wxCommandEvent& event)    { TogStyle(wxTR_ROW_LINES); }
+
     void OnDump(wxCommandEvent& event);
 #ifndef NO_MULTIPLE_SELECTION
     void OnDumpSelected(wxCommandEvent& event);
@@ -152,6 +166,7 @@ public:
     void OnDeleteAll(wxCommandEvent& event);
 
     void OnRecreate(wxCommandEvent& event);
+    void OnToggleButtons(wxCommandEvent& event);
     void OnToggleImages(wxCommandEvent& event);
     void OnSetImageSize(wxCommandEvent& event);
     void OnCollapseAndReset(wxCommandEvent& event);
@@ -182,6 +197,8 @@ public:
     void OnSize(wxSizeEvent& event);
 
 private:
+    void TogStyle(long flag);
+
     void DoSort(bool reverse = FALSE);
 
     void Resize(const wxSize& size);
@@ -199,20 +216,28 @@ enum
 {
     TreeTest_Quit,
     TreeTest_About,
+    TreeTest_TogButtons,
+    TreeTest_TogTwist,
+    TreeTest_TogLines,
+    TreeTest_TogEdit,
+    TreeTest_TogHideRoot,
+    TreeTest_TogRootLines,
+    TreeTest_TogBorder,
     TreeTest_Dump,
     TreeTest_DumpSelected,
     TreeTest_Count,
     TreeTest_CountRec,
     TreeTest_Sort,
     TreeTest_SortRev,
-    TreeTest_Bold,
-    TreeTest_UnBold,
+    TreeTest_SetBold,
+    TreeTest_ClearBold,
     TreeTest_Rename,
     TreeTest_Delete,
     TreeTest_DeleteChildren,
     TreeTest_DeleteAll,
     TreeTest_Recreate,
     TreeTest_ToggleImages,
+    TreeTest_ToggleButtons,
     TreeTest_SetImageSize,
     TreeTest_ToggleSel,
     TreeTest_CollapseAndReset,
index 8f7a71f1d309ae1a191a1f3ffd35333eb260fba3..7a268e719f28478050406e094e134201e08eb8f1 100644 (file)
@@ -49,6 +49,7 @@
 #include "wx/statbmp.h"
 #include "wx/gauge.h"
 #include "wx/textctrl.h"
+#include "wx/treebase.h"
 #include "wx/msgdlg.h"
 #include "wx/intl.h"
 #endif
index ddd3c5575d6472f24e2e2bf5625cb91a4263d306..dfa45202e5f962508fc258cf487b291ab86a0898 100644 (file)
@@ -67,8 +67,6 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_END_DRAG)
 // Tree event
 // ----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxNotifyEvent)
-
 wxTreeEvent::wxTreeEvent(wxEventType commandType, int id)
            : wxNotifyEvent(commandType, id)
 {
index ed3ad90ffef1a4a404055dcaa4a3058931aea879..da81aff51877c8b6ad5d416b97fa7fa654e2b5d3 100644 (file)
@@ -27,6 +27,7 @@
 #include "wx/button.h"
 #include "wx/layout.h"
 #include "wx/msgdlg.h"
+#include "wx/textctrl.h"
 #include "wx/textdlg.h"
 #include "wx/filefn.h"
 #include "wx/cmndata.h"
index d993b94ae7553ed5b5d02225c87af108bbf1bf36..b8bab14d3ff93815b0fa73ee47eb188b99188f78 100644 (file)
@@ -29,6 +29,7 @@
 #include "wx/button.h"
 #include "wx/layout.h"
 #include "wx/msgdlg.h"
+#include "wx/textctrl.h"
 #include "wx/textdlg.h"
 #include "wx/filefn.h"
 #include "wx/cmndata.h"
index 6c61c9f6e4d21ec2ab521069a6ca5aaf10aa3ec2..a4db0ea4fa1f2034f73c1ec6bef17722e8859a15 100644 (file)
 
 #if wxUSE_TREECTRL
 
+#include "wx/treebase.h"
 #include "wx/generic/treectlg.h"
+#include "wx/timer.h"
+#include "wx/textctrl.h"
 #include "wx/imaglist.h"
 #include "wx/settings.h"
-#include "wx/log.h"
-#include "wx/intl.h"
-#include "wx/dynarray.h"
-#include "wx/arrimpl.cpp"
 #include "wx/dcclient.h"
-#include "wx/msgdlg.h"
 
 // -----------------------------------------------------------------------------
 // array types
@@ -77,7 +75,6 @@ private:
 class WXDLLEXPORT wxTreeTextCtrl: public wxTextCtrl
 {
 public:
-    wxTreeTextCtrl() { }
     wxTreeTextCtrl( wxWindow *parent,
                     const wxWindowID id,
                     bool *accept,
@@ -97,11 +94,10 @@ public:
 private:
     bool               *m_accept;
     wxString           *m_res;
-    wxGenericTreeCtrl         *m_owner;
+    wxGenericTreeCtrl  *m_owner;
     wxString            m_startValue;
 
     DECLARE_EVENT_TABLE()
-    DECLARE_DYNAMIC_CLASS(wxTreeTextCtrl);
 };
 
 // a tree item
@@ -111,10 +107,11 @@ public:
     // ctors & dtor
     wxGenericTreeItem() { m_data = NULL; }
     wxGenericTreeItem( wxGenericTreeItem *parent,
-            const wxString& text,
-            wxDC& dc,
-            int image, int selImage,
-            wxTreeItemData *data );
+                       const wxString& text,
+                       wxDC& dc,
+                       int image,
+                       int selImage,
+                       wxTreeItemData *data );
 
     ~wxGenericTreeItem();
 
@@ -150,15 +147,12 @@ public:
     void SetHeight(int h) { m_height = h; }
     void SetWidth(int w) { m_width = w; }
 
-
     wxGenericTreeItem *GetParent() const { return m_parent; }
 
     // operations
         // deletes all children notifying the treectrl about it if !NULL
         // pointer given
     void DeleteChildren(wxGenericTreeCtrl *tree = NULL);
-        // FIXME don't know what is it for
-    void Reset();
 
     // get count of all children (and grand children if 'recursively')
     size_t GetChildrenCount(bool recursively = TRUE) const;
@@ -166,13 +160,15 @@ public:
     void Insert(wxGenericTreeItem *child, size_t index)
     { m_children.Insert(child, index); }
 
-    void SetCross( int x, int y );
     void GetSize( int &x, int &y, const wxGenericTreeCtrl* );
 
         // return the item at given position (or NULL if no item), onButton is
         // TRUE if the point belongs to the item's button, otherwise it lies
         // on the button's label
-    wxGenericTreeItem *HitTest( const wxPoint& point, const wxGenericTreeCtrl *, int &flags);
+    wxGenericTreeItem *HitTest( const wxPoint& point,
+                                const wxGenericTreeCtrl *,
+                                int &flags,
+                                int level );
 
     void Expand() { m_isCollapsed = FALSE; }
     void Collapse() { m_isCollapsed = TRUE; }
@@ -193,19 +189,47 @@ public:
     wxTreeItemAttr& Attr()
     {
         if ( !m_attr )
+        {
             m_attr = new wxTreeItemAttr;
-
+            m_ownsAttr = TRUE;
+        }
         return *m_attr;
     }
+        // set them
+    void SetAttributes(wxTreeItemAttr *attr)
+    {
+        if ( m_ownsAttr ) delete m_attr;
+        m_attr = attr;
+        m_ownsAttr = FALSE;
+    }
+        // set them and delete when done
+    void AssignAttributes(wxTreeItemAttr *attr)
+    {
+        SetAttributes(attr);
+        m_ownsAttr = TRUE;
+    }
 
 private:
-    wxString            m_text;
+    // since there can be very many of these, we save size by chosing
+    // the smallest representation for the elements and by ordering
+    // the members to avoid padding.
+    wxString            m_text;         // label to be rendered for item
+
+    wxTreeItemData     *m_data;         // user-provided data
+
+    wxArrayGenericTreeItems m_children; // list of children
+    wxGenericTreeItem  *m_parent;       // parent of this item
+
+    wxTreeItemAttr     *m_attr;         // attributes???
 
     // tree ctrl images for the normal, selected, expanded and
     // expanded+selected states
-    int                 m_images[wxTreeItemIcon_Max];
+    short               m_images[wxTreeItemIcon_Max];
 
-    wxTreeItemData     *m_data;
+    wxCoord             m_x;            // (virtual) offset from top
+    short               m_y;            // (virtual) offset from left
+    short               m_width;        // width of this item
+    unsigned char       m_height;       // height of this item
 
     // use bitfields to save size
     int                 m_isCollapsed :1;
@@ -213,16 +237,7 @@ private:
     int                 m_hasPlus     :1; // used for item which doesn't have
                                           // children but has a [+] button
     int                 m_isBold      :1; // render the label in bold font
-
-    wxCoord             m_x, m_y;
-    wxCoord             m_height, m_width;
-    int                 m_xCross, m_yCross;
-    int                 m_level;
-
-    wxArrayGenericTreeItems m_children;
-    wxGenericTreeItem  *m_parent;
-
-    wxTreeItemAttr     *m_attr;
+    int                 m_ownsAttr    :1; // delete attribute when done
 };
 
 // =============================================================================
@@ -265,8 +280,6 @@ void wxTreeRenameTimer::Notify()
 // wxTreeTextCtrl (internal)
 //-----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxTreeTextCtrl,wxTextCtrl);
-
 BEGIN_EVENT_TABLE(wxTreeTextCtrl,wxTextCtrl)
     EVT_CHAR           (wxTreeTextCtrl::OnChar)
     EVT_KEY_UP         (wxTreeTextCtrl::OnKeyUp)
@@ -284,7 +297,7 @@ wxTreeTextCtrl::wxTreeTextCtrl( wxWindow *parent,
                                 int style,
                                 const wxValidator& validator,
                                 const wxString &name )
-              : wxTextCtrl( parent, id, value, pos, size, style, validator, name )
+    : wxTextCtrl( parent, id, value, pos, size, style, validator, name )
 {
     m_res = res;
     m_accept = accept;
@@ -296,17 +309,18 @@ wxTreeTextCtrl::wxTreeTextCtrl( wxWindow *parent,
 
 void wxTreeTextCtrl::OnChar( wxKeyEvent &event )
 {
+    // TODO focus doesn't return to the wxTextCtrl when this closes...
     if (event.m_keyCode == WXK_RETURN)
     {
         (*m_accept) = TRUE;
         (*m_res) = GetValue();
 
-        if (!wxPendingDelete.Member(this))
-            wxPendingDelete.Append(this);
-
         if ((*m_accept) && ((*m_res) != m_startValue))
             m_owner->OnRenameAccept();
 
+        if (!wxPendingDelete.Member(this))
+            wxPendingDelete.Append(this);
+
         return;
     }
     if (event.m_keyCode == WXK_ESCAPE)
@@ -379,9 +393,6 @@ wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent,
 
     m_data = data;
     m_x = m_y = 0;
-    m_xCross = m_yCross = 0;
-
-    m_level = 0;
 
     m_isCollapsed = TRUE;
     m_hasHilight = FALSE;
@@ -391,6 +402,7 @@ wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent,
     m_parent = parent;
 
     m_attr = (wxTreeItemAttr *)NULL;
+    m_ownsAttr = FALSE;
 
     // We don't know the height here yet.
     m_width = 0;
@@ -401,7 +413,7 @@ wxGenericTreeItem::~wxGenericTreeItem()
 {
     delete m_data;
 
-    delete m_attr;
+    if (m_ownsAttr) delete m_attr;
 
     wxASSERT_MSG( m_children.IsEmpty(),
                   wxT("please call DeleteChildren() before deleting the item") );
@@ -428,28 +440,6 @@ void wxGenericTreeItem::SetText( const wxString &text )
     m_text = text;
 }
 
-void wxGenericTreeItem::Reset()
-{
-    m_text.Empty();
-    for ( int i = 0; i < wxTreeItemIcon_Max; i++ )
-    {
-        m_images[i] = NO_IMAGE;
-    }
-
-    m_data = NULL;
-    m_x = m_y =
-    m_height = m_width = 0;
-    m_xCross =
-    m_yCross = 0;
-
-    m_level = 0;
-
-    DeleteChildren();
-    m_isCollapsed = TRUE;
-
-    m_parent = (wxGenericTreeItem *)NULL;
-}
-
 size_t wxGenericTreeItem::GetChildrenCount(bool recursively) const
 {
     size_t count = m_children.Count();
@@ -465,15 +455,10 @@ size_t wxGenericTreeItem::GetChildrenCount(bool recursively) const
     return total;
 }
 
-void wxGenericTreeItem::SetCross( int x, int y )
-{
-    m_xCross = x;
-    m_yCross = y;
-}
-
-void wxGenericTreeItem::GetSize( int &x, int &y, const wxGenericTreeCtrl *theTree )
+void wxGenericTreeItem::GetSize( int &x, int &y,
+                                 const wxGenericTreeCtrl *theButton )
 {
-    int bottomY=m_y+theTree->GetLineHeight(this);
+    int bottomY=m_y+theButton->GetLineHeight(this);
     if ( y < bottomY ) y = bottomY;
     int width = m_x +  m_width;
     if ( x < width ) x = width;
@@ -483,71 +468,81 @@ void wxGenericTreeItem::GetSize( int &x, int &y, const wxGenericTreeCtrl *theTre
         size_t count = m_children.Count();
         for ( size_t n = 0; n < count; ++n )
         {
-            m_children[n]->GetSize( x, y, theTree );
+            m_children[n]->GetSize( x, y, theButton );
         }
     }
 }
 
-wxGenericTreeItem *wxGenericTreeItem::HitTest( const wxPoint& point,
-                                               const wxGenericTreeCtrl *theTree,
-                                               int &flags)
+wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point,
+                                              const wxGenericTreeCtrl *theCtrl,
+                                              int &flags,
+                                              int level)
 {
-    if ((point.y > m_y) && (point.y < m_y + theTree->GetLineHeight(this)))
+    // for a hidden root node, don't evaluate it, but do evaluate children
+    if ( !(level == 0 && theCtrl->HasFlag(wxTR_HIDE_ROOT)) )
     {
-        if (point.y < m_y+theTree->GetLineHeight(this)/2 )
-            flags |= wxTREE_HITTEST_ONITEMUPPERPART;
-        else
-            flags |= wxTREE_HITTEST_ONITEMLOWERPART;
-
-        // 5 is the size of the plus sign
-        if ((point.x > m_xCross-5) && (point.x < m_xCross+5) &&
-            (point.y > m_yCross-5) && (point.y < m_yCross+5) &&
-            (IsExpanded() || HasPlus()))
+        // evaluate the item
+        int h = theCtrl->GetLineHeight(this);
+        if ((point.y > m_y) && (point.y < m_y + h))
         {
-            flags|=wxTREE_HITTEST_ONITEMBUTTON;
-            return this;
-        }
+            int y_mid = m_y + h/2;
+            if (point.y < y_mid )
+                flags |= wxTREE_HITTEST_ONITEMUPPERPART;
+            else
+                flags |= wxTREE_HITTEST_ONITEMLOWERPART;
 
-        if ((point.x >= m_x) && (point.x <= m_x+m_width))
-        {
-            int image_w = -1;
-            int image_h;
+            // 5 is the size of the plus sign
+            int xCross = m_x - theCtrl->GetSpacing();
+            if ((point.x > xCross-5) && (point.x < xCross+5) &&
+                (point.y > y_mid-5) && (point.y < y_mid+5) &&
+                HasPlus() && theCtrl->HasButtons() )
+            {
+                flags |= wxTREE_HITTEST_ONITEMBUTTON;
+                return this;
+            }
 
-            // assuming every image (normal and selected ) has the same size !
-            if ( (GetImage() != NO_IMAGE) && theTree->m_imageListNormal )
-                theTree->m_imageListNormal->GetSize(GetImage(), image_w, image_h);
+            if ((point.x >= m_x) && (point.x <= m_x+m_width))
+            {
+                int image_w = -1;
+                int image_h;
 
-            if ((image_w != -1) && (point.x <= m_x + image_w + 1))
-                flags |= wxTREE_HITTEST_ONITEMICON;
-            else
-                flags |= wxTREE_HITTEST_ONITEMLABEL;
+                // assuming every image (normal and selected) has the same size!
+                if ( (GetImage() != NO_IMAGE) && theCtrl->m_imageListNormal )
+                    theCtrl->m_imageListNormal->GetSize(GetImage(),
+                                                        image_w, image_h);
+
+                if ((image_w != -1) && (point.x <= m_x + image_w + 1))
+                    flags |= wxTREE_HITTEST_ONITEMICON;
+                else
+                    flags |= wxTREE_HITTEST_ONITEMLABEL;
+
+                return this;
+            }
+
+            if (point.x < m_x)
+                flags |= wxTREE_HITTEST_ONITEMINDENT;
+            if (point.x > m_x+m_width)
+                flags |= wxTREE_HITTEST_ONITEMRIGHT;
 
             return this;
         }
 
-        if (point.x < m_x)
-            flags |= wxTREE_HITTEST_ONITEMINDENT;
-        if (point.x > m_x+m_width)
-            flags |= wxTREE_HITTEST_ONITEMRIGHT;
-
-        return this;
+        // if children are expanded, fall through to evaluate them
+        if (m_isCollapsed) return (wxGenericTreeItem*) NULL;
     }
-    else
+
+    // evaluate children
+    size_t count = m_children.Count();
+    for ( size_t n = 0; n < count; n++ )
     {
-        if (!m_isCollapsed)
-        {
-            size_t count = m_children.Count();
-            for ( size_t n = 0; n < count; n++ )
-            {
-                wxGenericTreeItem *res = m_children[n]->HitTest( point, theTree, flags );
-                if ( res != NULL )
-                    return res;
-            }
-        }
+        wxGenericTreeItem *res = m_children[n]->HitTest( point,
+                                                         theCtrl,
+                                                         flags,
+                                                         level + 1 );
+        if ( res != NULL )
+            return res;
     }
 
-    flags|=wxTREE_HITTEST_NOWHERE;
-
     return (wxGenericTreeItem*) NULL;
 }
 
@@ -574,12 +569,9 @@ int wxGenericTreeItem::GetCurrentImage() const
             image = GetImage(wxTreeItemIcon_Selected);
     }
 
-    // may be it doesn't have the specific image we want, try the default one
-    // instead
-    if ( image == NO_IMAGE )
-    {
-        image = GetImage();
-    }
+    // maybe it doesn't have the specific image we want,
+    // try the default one instead
+    if ( image == NO_IMAGE ) image = GetImage();
 
     return image;
 }
@@ -599,7 +591,7 @@ BEGIN_EVENT_TABLE(wxGenericTreeCtrl,wxScrolledWindow)
     EVT_IDLE           (wxGenericTreeCtrl::OnIdle)
 END_EVENT_TABLE()
 
-#if !defined(__WXMSW__) || defined(__WIN16__)
+#if !defined(__WXMSW__) || defined(__WIN16__) || defined(__WXUNIVERSAL__)
 /*
  * wxTreeCtrl has to be a real class or we have problems with
  * the run-time information.
@@ -614,52 +606,57 @@ IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxGenericTreeCtrl)
 
 void wxGenericTreeCtrl::Init()
 {
-    m_current =
-    m_key_current =
-    m_anchor = (wxGenericTreeItem *) NULL;
+    m_current = m_key_current = m_anchor = (wxGenericTreeItem *) NULL;
     m_hasFocus = FALSE;
     m_dirty = FALSE;
 
-    m_xScroll = 0;
-    m_yScroll = 0;
     m_lineHeight = 10;
     m_indent = 15;
     m_spacing = 18;
 
-    m_hilightBrush = new wxBrush
-    (
-      wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT),
-      wxSOLID
-    );
+    m_hilightBrush = new wxBrush(
+               wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT),
+               wxSOLID);
 
-    m_imageListNormal =
+    m_imageListNormal = m_imageListButtons =
     m_imageListState = (wxImageList *) NULL;
-    m_ownsImageListNormal =
+    m_ownsImageListNormal = m_ownsImageListButtons =
     m_ownsImageListState = FALSE;
 
     m_dragCount = 0;
     m_isDragging = FALSE;
-    m_dropTarget =
-    m_oldSelection = (wxGenericTreeItem *)NULL;
+    m_dropTarget = m_oldSelection = (wxGenericTreeItem *)NULL;
 
     m_renameTimer = new wxTreeRenameTimer( this );
     m_lastOnSame = FALSE;
 
     m_normalFont = wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT );
     m_boldFont = wxFont( m_normalFont.GetPointSize(),
-                            m_normalFont.GetFamily(),
-                            m_normalFont.GetStyle(),
-                            wxBOLD,
-                            m_normalFont.GetUnderlined());
+                         m_normalFont.GetFamily(),
+                         m_normalFont.GetStyle(),
+                         wxBOLD,
+                         m_normalFont.GetUnderlined());
 }
 
-bool wxGenericTreeCtrl::Create(wxWindow *parent, wxWindowID id,
-                        const wxPoint& pos, const wxSize& size,
-                        long style,
-                        const wxValidator &validator,
-                        const wxString& name )
+bool wxGenericTreeCtrl::Create(wxWindow *parent,
+                               wxWindowID id,
+                               const wxPoint& pos,
+                               const wxSize& size,
+                               long style,
+                               const wxValidator &validator,
+                               const wxString& name )
 {
-    wxScrolledWindow::Create( parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, name );
+    wxScrolledWindow::Create( parent, id, pos, size,
+                              style|wxHSCROLL|wxVSCROLL, name );
+
+        // If the tree display has no buttons, but does have
+        // connecting lines, we can use a narrower layout.
+        // It may not be a good idea to force this...
+    if (!HasButtons() && !HasFlag(wxTR_NO_LINES))
+    {
+        m_indent= 10;
+        m_spacing = 10;
+    }
 
 #if wxUSE_VALIDATORS
     SetValidator( validator );
@@ -682,6 +679,7 @@ wxGenericTreeCtrl::~wxGenericTreeCtrl()
     delete m_renameTimer;
     if (m_ownsImageListNormal) delete m_imageListNormal;
     if (m_ownsImageListState) delete m_imageListState;
+    if (m_ownsImageListButtons) delete m_imageListButtons;
 }
 
 // -----------------------------------------------------------------------------
@@ -712,6 +710,15 @@ size_t wxGenericTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recurs
     return ((wxGenericTreeItem*) item.m_pItem)->GetChildrenCount(recursively);
 }
 
+void wxGenericTreeCtrl::SetWindowStyle(const long styles)
+{
+        // right now, just sets the styles.  Eventually, we may
+        // want to update the inherited styles, but right now
+        // none of the parents has updatable styles
+    m_windowStyle = styles;
+    m_dirty = TRUE;
+}
+
 // -----------------------------------------------------------------------------
 // functions to work with tree items
 // -----------------------------------------------------------------------------
@@ -906,157 +913,158 @@ bool wxGenericTreeCtrl::IsBold(const wxTreeItemId& item) const
 
 wxTreeItemId wxGenericTreeCtrl::GetParent(const wxTreeItemId& item) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-  return ((wxGenericTreeItem*) item.m_pItem)->GetParent();
+    return ((wxGenericTreeItem*) item.m_pItem)->GetParent();
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetFirstChild(const wxTreeItemId& item, long& cookie) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-  cookie = 0;
-  return GetNextChild(item, cookie);
+    cookie = 0;
+    return GetNextChild(item, cookie);
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetNextChild(const wxTreeItemId& item, long& cookie) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-  wxArrayGenericTreeItems& children = ((wxGenericTreeItem*) item.m_pItem)->GetChildren();
-  if ( (size_t)cookie < children.Count() )
-  {
-    return children.Item((size_t)cookie++);
-  }
-  else
-  {
-    // there are no more of them
-    return wxTreeItemId();
-  }
+    wxArrayGenericTreeItems& children = ((wxGenericTreeItem*) item.m_pItem)->GetChildren();
+    if ( (size_t)cookie < children.Count() )
+    {
+        return children.Item((size_t)cookie++);
+    }
+    else
+    {
+        // there are no more of them
+        return wxTreeItemId();
+    }
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetLastChild(const wxTreeItemId& item) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-  wxArrayGenericTreeItems& children = ((wxGenericTreeItem*) item.m_pItem)->GetChildren();
-  return (children.IsEmpty() ? wxTreeItemId() : wxTreeItemId(children.Last()));
+    wxArrayGenericTreeItems& children = ((wxGenericTreeItem*) item.m_pItem)->GetChildren();
+    return (children.IsEmpty() ? wxTreeItemId() : wxTreeItemId(children.Last()));
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetNextSibling(const wxTreeItemId& item) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-  wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
-  wxGenericTreeItem *parent = i->GetParent();
-  if ( parent == NULL )
-  {
-    // root item doesn't have any siblings
-    return wxTreeItemId();
-  }
+    wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
+    wxGenericTreeItem *parent = i->GetParent();
+    if ( parent == NULL )
+    {
+        // root item doesn't have any siblings
+        return wxTreeItemId();
+    }
 
-  wxArrayGenericTreeItems& siblings = parent->GetChildren();
-  int index = siblings.Index(i);
-  wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
+    wxArrayGenericTreeItems& siblings = parent->GetChildren();
+    int index = siblings.Index(i);
+    wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
 
-  size_t n = (size_t)(index + 1);
-  return n == siblings.Count() ? wxTreeItemId() : wxTreeItemId(siblings[n]);
+    size_t n = (size_t)(index + 1);
+    return n == siblings.Count() ? wxTreeItemId() : wxTreeItemId(siblings[n]);
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-  wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
-  wxGenericTreeItem *parent = i->GetParent();
-  if ( parent == NULL )
-  {
-    // root item doesn't have any siblings
-    return wxTreeItemId();
-  }
+    wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
+    wxGenericTreeItem *parent = i->GetParent();
+    if ( parent == NULL )
+    {
+        // root item doesn't have any siblings
+        return wxTreeItemId();
+    }
 
-  wxArrayGenericTreeItems& siblings = parent->GetChildren();
-  int index = siblings.Index(i);
-  wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
+    wxArrayGenericTreeItems& siblings = parent->GetChildren();
+    int index = siblings.Index(i);
+    wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
 
-  return index == 0 ? wxTreeItemId()
-                    : wxTreeItemId(siblings[(size_t)(index - 1)]);
+    return index == 0 ? wxTreeItemId()
+                      : wxTreeItemId(siblings[(size_t)(index - 1)]);
 }
 
 // Only for internal use right now, but should probably be public
 wxTreeItemId wxGenericTreeCtrl::GetNext(const wxTreeItemId& item) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
-
-  wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
-
-  // First see if there are any children.
-  wxArrayGenericTreeItems& children = i->GetChildren();
-  if (children.GetCount() > 0)
-  {
-     return children.Item(0);
-  }
-  else
-  {
-     // Try a sibling of this or ancestor instead
-     wxTreeItemId p = item;
-     wxTreeItemId toFind;
-     do
-     {
-        toFind = GetNextSibling(p);
-        p = GetParent(p);
-     } while (p.IsOk() && !toFind.IsOk());
-     return toFind;
-  }
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+
+    wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
+
+    // First see if there are any children.
+    wxArrayGenericTreeItems& children = i->GetChildren();
+    if (children.GetCount() > 0)
+    {
+         return children.Item(0);
+    }
+    else
+    {
+         // Try a sibling of this or ancestor instead
+         wxTreeItemId p = item;
+         wxTreeItemId toFind;
+         do
+         {
+              toFind = GetNextSibling(p);
+              p = GetParent(p);
+         } while (p.IsOk() && !toFind.IsOk());
+         return toFind;
+    }
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetPrev(const wxTreeItemId& item) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-  wxFAIL_MSG(wxT("not implemented"));
+    wxFAIL_MSG(wxT("not implemented"));
 
-  return wxTreeItemId();
+    return wxTreeItemId();
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetFirstVisibleItem() const
 {
-  wxTreeItemId id = GetRootItem();
-  if (!id.IsOk())
-    return id;
-
-  do
-  {
-    if (IsVisible(id))
+    wxTreeItemId id = GetRootItem();
+    if (!id.IsOk())
         return id;
-    id = GetNext(id);
-  } while (id.IsOk());
 
-  return wxTreeItemId();
+    do
+    {
+        if (IsVisible(id))
+              return id;
+        id = GetNext(id);
+    } while (id.IsOk());
+
+    return wxTreeItemId();
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetNextVisible(const wxTreeItemId& item) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
-
-  wxTreeItemId id = item;
-  while (id.IsOk())
-  {
-      id = GetNext(id);
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-      if (id.IsOk() && IsVisible(id))
-          return id;
-  }
-  return wxTreeItemId();
+    wxTreeItemId id = item;
+    if (id.IsOk())
+    {
+        while (id = GetNext(id), id.IsOk())
+        {
+            if (IsVisible(id))
+                return id;
+        }
+    }
+    return wxTreeItemId();
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
 {
-  wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-  wxFAIL_MSG(wxT("not implemented"));
+    wxFAIL_MSG(wxT("not implemented"));
 
-  return wxTreeItemId();
+    return wxTreeItemId();
 }
 
 // -----------------------------------------------------------------------------
@@ -1076,6 +1084,8 @@ wxTreeItemId wxGenericTreeCtrl::DoInsertItem(const wxTreeItemId& parentId,
         return AddRoot(text, image, selImage, data);
     }
 
+    m_dirty = TRUE;     // do this first so stuff below doesn't cause flicker
+
     wxClientDC dc(this);
     wxGenericTreeItem *item =
         new wxGenericTreeItem( parent, text, dc, image, selImage, data );
@@ -1087,8 +1097,6 @@ wxTreeItemId wxGenericTreeCtrl::DoInsertItem(const wxTreeItemId& parentId,
 
     parent->Insert( item, previous );
 
-    m_dirty = TRUE;
-
     return item;
 }
 
@@ -1098,9 +1106,18 @@ wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text,
 {
     wxCHECK_MSG( !m_anchor, wxTreeItemId(), wxT("tree can have only one root") );
 
+    m_dirty = TRUE;     // do this first so stuff below doesn't cause flicker
+
     wxClientDC dc(this);
     m_anchor = new wxGenericTreeItem((wxGenericTreeItem *)NULL, text, dc,
                                    image, selImage, data);
+    if (HasFlag(wxTR_HIDE_ROOT))
+    {
+        // if root is hidden, make sure we can navigate
+        // into children
+        m_anchor->SetHasPlus();
+        Expand(m_anchor);
+    }
     if ( data != NULL )
     {
         data->m_pItem = (long) m_anchor;
@@ -1112,8 +1129,6 @@ wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text,
         m_current->SetHilight( TRUE );
     }
 
-    m_dirty = TRUE;
-
     return m_anchor;
 }
 
@@ -1187,31 +1202,31 @@ void wxGenericTreeCtrl::SendDeleteEvent(wxGenericTreeItem *item)
 
 void wxGenericTreeCtrl::DeleteChildren(const wxTreeItemId& itemId)
 {
+    m_dirty = TRUE;     // do this first so stuff below doesn't cause flicker
+
     wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
     item->DeleteChildren(this);
-
-    m_dirty = TRUE;
 }
 
 void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
 {
+    m_dirty = TRUE;     // do this first so stuff below doesn't cause flicker
+
     wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
 
-    // don't stay with invalid m_key_current or we will crash in the next call
-    // to OnChar()
+    // don't stay with invalid m_key_current or we will crash in
+    // the next call to OnChar()
     bool changeKeyCurrent = FALSE;
     wxGenericTreeItem *itemKey = m_key_current;
-    while ( itemKey && !changeKeyCurrent )
+    while ( itemKey )
     {
         if ( itemKey == item )
         {
             // m_key_current is a descendant of the item being deleted
             changeKeyCurrent = TRUE;
+            break;
         }
-        else
-        {
-            itemKey = itemKey->GetParent();
-        }
+        itemKey = itemKey->GetParent();
     }
 
     wxGenericTreeItem *parent = item->GetParent();
@@ -1229,20 +1244,18 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
     item->DeleteChildren(this);
     SendDeleteEvent(item);
     delete item;
-
-    m_dirty = TRUE;
 }
 
 void wxGenericTreeCtrl::DeleteAllItems()
 {
     if ( m_anchor )
     {
+        m_dirty = TRUE;
+
         m_anchor->DeleteChildren(this);
         delete m_anchor;
 
         m_anchor = NULL;
-
-        m_dirty = TRUE;
     }
 }
 
@@ -1311,12 +1324,14 @@ void wxGenericTreeCtrl::Collapse(const wxTreeItemId& itemId)
 
     item->Collapse();
 
+#if 0  // TODO why should items be collapsed recursively?
     wxArrayGenericTreeItems& children = item->GetChildren();
     size_t count = children.Count();
     for ( size_t n = 0; n < count; n++ )
     {
         Collapse(children[n]);
     }
+#endif
 
     CalculatePositions();
 
@@ -1483,7 +1498,7 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId,
     // TODO : Here we don't send any selection mode yet !
 
     if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() )
-      return;
+        return;
 
     wxTreeItemId parent = GetParent( itemId );
     while (parent.IsOk())
@@ -1508,8 +1523,7 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId,
     {
         if ( !m_current )
         {
-            m_current =
-            m_key_current = (wxGenericTreeItem*) GetRootItem().m_pItem;
+            m_current = m_key_current = (wxGenericTreeItem*) GetRootItem().m_pItem;
         }
 
         // don't change the mark (m_current)
@@ -1521,7 +1535,7 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId,
 
         // Check if we need to toggle hilight (ctrl mode)
         if (!unselect_others)
-          select=!item->IsSelected();
+            select=!item->IsSelected();
 
         m_current = m_key_current = item;
         m_current->SetHilight(select);
@@ -1549,15 +1563,15 @@ void wxGenericTreeCtrl::FillArray(wxGenericTreeItem *item,
 
 size_t wxGenericTreeCtrl::GetSelections(wxArrayTreeItemIds &array) const
 {
-  array.Empty();
-  wxTreeItemId idRoot = GetRootItem();
-  if ( idRoot.IsOk() )
-  {
-      FillArray((wxGenericTreeItem*) idRoot.m_pItem, array);
-  }
-  //else: the tree is empty, so no selections
+    array.Empty();
+    wxTreeItemId idRoot = GetRootItem();
+    if ( idRoot.IsOk() )
+    {
+        FillArray((wxGenericTreeItem*) idRoot.m_pItem, array);
+    }
+    //else: the tree is empty, so no selections
 
-  return array.Count();
+    return array.Count();
 }
 
 void wxGenericTreeCtrl::EnsureVisible(const wxTreeItemId& item)
@@ -1658,11 +1672,11 @@ void wxGenericTreeCtrl::SortChildren(const wxTreeItemId& itemId)
     wxArrayGenericTreeItems& children = item->GetChildren();
     if ( children.Count() > 1 )
     {
+        m_dirty = TRUE;
+
         s_treeBeingSorted = this;
         children.Sort(tree_ctrl_compare_func);
         s_treeBeingSorted = NULL;
-
-        m_dirty = TRUE;
     }
     //else: don't make the tree dirty as nothing changed
 }
@@ -1672,41 +1686,64 @@ wxImageList *wxGenericTreeCtrl::GetImageList() const
     return m_imageListNormal;
 }
 
+wxImageList *wxGenericTreeCtrl::GetButtonsImageList() const
+{
+    return m_imageListButtons;
+}
+
 wxImageList *wxGenericTreeCtrl::GetStateImageList() const
 {
     return m_imageListState;
 }
 
-void wxGenericTreeCtrl::SetImageList(wxImageList *imageList)
+void wxGenericTreeCtrl::CalculateLineHeight()
 {
-    if (m_ownsImageListNormal) delete m_imageListNormal;
-
-    m_imageListNormal = imageList;
-    m_ownsImageListNormal = FALSE;
-
-    if ( !m_imageListNormal )
-        return;
-
-    // Calculate a m_lineHeight value from the image sizes.
-    // May be toggle off. Then wxGenericTreeCtrl will spread when
-    // necessary (which might look ugly).
     wxClientDC dc(this);
     m_lineHeight = (int)(dc.GetCharHeight() + 4);
-    int width = 0, height = 0,
-        n = m_imageListNormal->GetImageCount();
 
-    for (int i = 0; i < n ; i++)
+    if ( m_imageListNormal )
+    {
+        // Calculate a m_lineHeight value from the normal Image sizes.
+        // May be toggle off. Then wxGenericTreeCtrl will spread when
+        // necessary (which might look ugly).
+        int n = m_imageListNormal->GetImageCount();
+        for (int i = 0; i < n ; i++)
+        {
+            int width = 0, height = 0;
+            m_imageListNormal->GetSize(i, width, height);
+            if (height > m_lineHeight) m_lineHeight = height;
+        }
+    }
+
+    if (m_imageListButtons)
     {
-        m_imageListNormal->GetSize(i, width, height);
-        if (height > m_lineHeight) m_lineHeight = height;
+        // Calculate a m_lineHeight value from the Button image sizes.
+        // May be toggle off. Then wxGenericTreeCtrl will spread when
+        // necessary (which might look ugly).
+        int n = m_imageListButtons->GetImageCount();
+        for (int i = 0; i < n ; i++)
+        {
+            int width = 0, height = 0;
+            m_imageListButtons->GetSize(i, width, height);
+            if (height > m_lineHeight) m_lineHeight = height;
+        }
     }
 
-    if (m_lineHeight < 40)
+    if (m_lineHeight < 30)
         m_lineHeight += 2;                 // at least 2 pixels
     else
         m_lineHeight += m_lineHeight/10;   // otherwise 10% extra spacing
 }
 
+void wxGenericTreeCtrl::SetImageList(wxImageList *imageList)
+{
+    if (m_ownsImageListNormal) delete m_imageListNormal;
+    m_imageListNormal = imageList;
+    m_ownsImageListNormal = FALSE;
+    m_dirty = TRUE;
+    CalculateLineHeight();
+}
+
 void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList)
 {
     if (m_ownsImageListState) delete m_imageListState;
@@ -1714,6 +1751,15 @@ void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList)
     m_ownsImageListState = FALSE;
 }
 
+void wxGenericTreeCtrl::SetButtonsImageList(wxImageList *imageList)
+{
+    if (m_ownsImageListButtons) delete m_imageListButtons;
+    m_imageListButtons = imageList;
+    m_ownsImageListButtons = FALSE;
+    m_dirty = TRUE;
+    CalculateLineHeight();
+}
+
 void wxGenericTreeCtrl::AssignImageList(wxImageList *imageList)
 {
     SetImageList(imageList);
@@ -1726,6 +1772,12 @@ void wxGenericTreeCtrl::AssignStateImageList(wxImageList *imageList)
     m_ownsImageListState = TRUE;
 }
 
+void wxGenericTreeCtrl::AssignButtonsImageList(wxImageList *imageList)
+{
+    SetButtonsImageList(imageList);
+    m_ownsImageListButtons = TRUE;
+}
+
 // -----------------------------------------------------------------------------
 // helpers
 // -----------------------------------------------------------------------------
@@ -1734,8 +1786,7 @@ void wxGenericTreeCtrl::AdjustMyScrollbars()
 {
     if (m_anchor)
     {
-        int x = 0;
-        int y = 0;
+        int x = 0, y = 0;
         m_anchor->GetSize( x, y, this );
         y += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
         x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
@@ -1759,18 +1810,18 @@ int wxGenericTreeCtrl::GetLineHeight(wxGenericTreeItem *item) const
 
 void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
 {
+    // TODO implement "state" icon on items
+
     wxTreeItemAttr *attr = item->GetAttributes();
     if ( attr && attr->HasFont() )
         dc.SetFont(attr->GetFont());
     else if (item->IsBold())
         dc.SetFont(m_boldFont);
 
-    long text_w = 0;
-    long text_h = 0;
+    long text_w = 0, text_h = 0;
     dc.GetTextExtent( item->GetText(), &text_w, &text_h );
 
-    int image_h = 0;
-    int image_w = 0;
+    int image_h = 0, image_w = 0;
     int image = item->GetCurrentImage();
     if ( image != NO_IMAGE )
     {
@@ -1841,103 +1892,129 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
 // Now y stands for the top of the item, whereas it used to stand for middle !
 void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &y )
 {
-    int x = (level+1)*m_indent;
-
-    item->SetX( x+m_spacing );
-    item->SetY( y );
-
-    int oldY = y;
-    y+=GetLineHeight(item)/2;
+    int x = level*m_indent;
+    if (!HasFlag(wxTR_HIDE_ROOT))
+    {
+        x += m_indent;
+    }
+    else if (level == 0)
+    {
+        wxArrayGenericTreeItems& children = item->GetChildren();
+        size_t n, count = children.Count();
+        for (n = 0; n < count; ++n)
+            PaintLevel(children[n], dc, 1, y);
+        return;
+    }
 
-    item->SetCross( x, y );
+    item->SetX(x+m_spacing);
+    item->SetY(y);
 
-    int exposed_x = dc.LogicalToDeviceX( 0 );
-    int exposed_y = dc.LogicalToDeviceY( item->GetY() );
+    int h = GetLineHeight(item);
+    int y_top = y;
+    int y_mid = y_top + (h>>1);
+    y += h;
 
-    bool drawLines = (!HasFlag(wxTR_NO_LINES) && !HasFlag(wxTR_MAC_BUTTONS));
+    int exposed_x = dc.LogicalToDeviceX(0);
+    int exposed_y = dc.LogicalToDeviceY(y_top);
 
-    if (IsExposed( exposed_x, exposed_y, 10000, GetLineHeight(item) ))  // 10000 = very much
+    if (IsExposed(exposed_x, exposed_y, 10000, h))  // 10000 = very much
     {
-        int startX = x - m_indent;
-        int endX = x-5;
-
-        if (!item->HasChildren()) endX += 20;
-
-        if (HasFlag( wxTR_MAC_BUTTONS ))
+        if (item->HasPlus() && HasButtons())  // should the item show a button?
         {
-            if (item->HasPlus())
+            if (!HasFlag(wxTR_NO_LINES))
+            {
+                if (x > (signed)m_indent || HasFlag(wxTR_LINES_AT_ROOT))
+                    dc.DrawLine(x - m_indent, y_mid, x - 5, y_mid);
+                dc.DrawLine(x + 5, y_mid, x + m_spacing, y_mid);
+            }
+
+            if (m_imageListButtons != NULL)
             {
-                dc.SetPen( *wxBLACK_PEN );
-                dc.SetBrush( *m_hilightBrush );
+                // draw the image button here
+                int image_h = 0, image_w = 0, image = wxCLOSED_BUTTON;
+                if (item->IsExpanded()) image = wxOPEN_BUTTON;
+                if (item->IsSelected())
+                    image += wxOPEN_BUTTON_SELECTED - wxOPEN_BUTTON;
+                m_imageListButtons->GetSize(image, image_w, image_h);
+                int xx = x - (image_w>>1);
+                int yy = y_mid - (image_h>>1);
+                dc.SetClippingRegion(xx, yy, image_w, image_h);
+                m_imageListButtons->Draw(image, dc, xx, yy,
+                                         wxIMAGELIST_DRAW_TRANSPARENT);
+                dc.DestroyClippingRegion();
+            }
+            else if (HasFlag(wxTR_TWIST_BUTTONS))
+            {
+                // draw the twisty button here
+                dc.SetPen(*wxBLACK_PEN);
+                dc.SetBrush(*m_hilightBrush);
 
                 wxPoint button[3];
 
                 if (item->IsExpanded())
                 {
                     button[0].x = x-5;
-                    button[0].y = y-2;
+                    button[0].y = y_mid-2;
                     button[1].x = x+5;
-                    button[1].y = y-2;
+                    button[1].y = y_mid-2;
                     button[2].x = x;
-                    button[2].y = y+3;
+                    button[2].y = y_mid+3;
                 }
                 else
                 {
-                    button[0].y = y-5;
+                    button[0].y = y_mid-5;
                     button[0].x = x-2;
-                    button[1].y = y+5;
+                    button[1].y = y_mid+5;
                     button[1].x = x-2;
-                    button[2].y = y;
+                    button[2].y = y_mid;
                     button[2].x = x+3;
                 }
-                dc.DrawPolygon( 3, button );
+                dc.DrawPolygon(3, button);
 
-                dc.SetPen( m_dottedPen );
+                dc.SetPen(m_dottedPen);
             }
-        }
-        else
-        {
-            if (drawLines)
-                dc.DrawLine( startX, y, endX, y );
-
-            if (item->HasPlus())
+            else // if (HasFlag(wxTR_HAS_BUTTONS))
             {
-                if (drawLines)
-                    dc.DrawLine( x+5, y, x+15, y );
-                dc.SetPen( *wxGREY_PEN );
-                dc.SetBrush( *wxWHITE_BRUSH );
-                dc.DrawRectangle( x-5, y-4, 11, 9 );
-
-                dc.SetPen( *wxBLACK_PEN );
-                dc.DrawLine( x-2, y, x+3, y );
+                // draw the plus sign here
+                dc.SetPen(*wxGREY_PEN);
+                dc.SetBrush(*wxWHITE_BRUSH);
+                dc.DrawRectangle(x-5, y_mid-4, 11, 9);
+                dc.SetPen(*wxBLACK_PEN);
+                dc.DrawLine(x-2, y_mid, x+3, y_mid);
                 if (!item->IsExpanded())
-                    dc.DrawLine( x, y-2, x, y+3 );
-                dc.SetPen( m_dottedPen );
+                    dc.DrawLine(x, y_mid-2, x, y_mid+3);
+                dc.SetPen(m_dottedPen);
             }
         }
+        else if (!HasFlag(wxTR_NO_LINES))  // no button; maybe a line?
+        {
+            // draw the horizontal line here
+            int x_start = x;
+            if (x > (signed)m_indent || HasFlag(wxTR_LINES_AT_ROOT))
+                x_start -= m_indent;
+            dc.DrawLine(x_start, y_mid, x + m_spacing, y_mid);
+        }
 
-        wxPen *pen;
+        wxPen *pen =
 #ifndef __WXMAC__
-        // don't draw rect outline if we already have the background color
-        // under Max
-        if ( item->IsSelected() )
-            pen = wxBLACK_PEN;
-        else
+            // don't draw rect outline if we already have the
+            // background color under Mac
+            (item->IsSelected()) ? wxBLACK_PEN :
 #endif // !__WXMAC__
-            pen = wxTRANSPARENT_PEN;
+            wxTRANSPARENT_PEN;
 
         wxColour colText;
-        if ( item->IsSelected() && m_hasFocus )
+        if (item->IsSelected() && m_hasFocus)
         {
-            colText = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT );
+            colText = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
         }
         else
         {
             wxTreeItemAttr *attr = item->GetAttributes();
-            if ( attr && attr->HasTextColour() )
+            if (attr && attr->HasTextColour())
                 colText = attr->GetTextColour();
             else
-                colText = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOWTEXT );
+                colText = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT);
         }
 
         // prepare to draw
@@ -1947,42 +2024,39 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
         // draw
         PaintItem(item, dc);
 
-        if (HasFlag( wxTR_ROW_LINES ))
+        if (HasFlag(wxTR_ROW_LINES))
         {
-            dc.SetPen( *wxWHITE_PEN );
-            dc.DrawLine( 0, oldY, 10000, oldY );
-            dc.DrawLine( 0, oldY + GetLineHeight(item), 10000, oldY + GetLineHeight(item) );
+            dc.SetPen(*wxWHITE_PEN);
+            dc.DrawLine(0, y_top, 10000, y_top);
+            dc.DrawLine(0, y, 10000, y);
         }
 
         // restore DC objects
-        dc.SetBrush( *wxWHITE_BRUSH );
-        dc.SetPen( m_dottedPen );
-        dc.SetTextForeground( *wxBLACK );
+        dc.SetBrush(*wxWHITE_BRUSH);
+        dc.SetPen(m_dottedPen);
+        dc.SetTextForeground(*wxBLACK);
     }
 
-    y = oldY+GetLineHeight(item);
-
     if (item->IsExpanded())
     {
-        oldY+=GetLineHeight(item)/2;
-        int semiOldY=0;
-
         wxArrayGenericTreeItems& children = item->GetChildren();
-        size_t n, count = children.Count();
-        for ( n = 0; n < count; ++n )
-        {
-            semiOldY=y;
-            PaintLevel( children[n], dc, level+1, y );
-        }
-
-        // it may happen that the item is expanded but has no items (when you
-        // delete all its children for example) - don't draw the vertical line
-        // in this case
+        int count = children.Count();
         if (count > 0)
         {
-            semiOldY+=GetLineHeight(children[--n])/2;
-            if (drawLines)
-                dc.DrawLine( x, oldY+5, x, semiOldY );
+            int n = 0, oldY;
+            ++level;
+            do {
+                oldY = y;
+                PaintLevel(children[n], dc, level, y);
+            } while (++n < count);
+
+            if (!HasFlag(wxTR_NO_LINES))
+            {
+                // draw line down to last child
+                oldY += GetLineHeight(children[n-1])/2;
+                if (HasButtons()) y_mid += 5;
+                dc.DrawLine(x, y_mid, x, oldY);
+            }
         }
     }
 }
@@ -2157,19 +2231,24 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
             }
             break;
 
-            // up goes to the previous sibling or to the last of its children if
-            // it's expanded
+            // up goes to the previous sibling or to the last
+            // of its children if it's expanded
         case WXK_UP:
             {
                 wxTreeItemId prev = GetPrevSibling( m_key_current );
                 if (!prev)
                 {
                     prev = GetParent( m_key_current );
+                    if ((prev == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT))
+                    {
+                        break;  // don't go to root if it is hidden
+                    }
                     if (prev)
                     {
-                        long cockie = 0;
+                        long cookie = 0;
                         wxTreeItemId current = m_key_current;
-                        if (current == GetFirstChild( prev, cockie ))
+                        // TODO: Huh?  If we get here, we'd better be the first child of our parent.  How else could it be?
+                        if (current == GetFirstChild( prev, cookie ))
                         {
                             // otherwise we return to where we came from
                             SelectItem( prev, unselect_others, extended_select );
@@ -2201,6 +2280,11 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
         case WXK_LEFT:
             {
                 wxTreeItemId prev = GetParent( m_current );
+                if ((prev == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT))
+                {
+                    // don't go to root if it is hidden
+                    prev = GetPrevSibling( m_current );
+                }
                 if (prev)
                 {
                     EnsureVisible( prev );
@@ -2210,8 +2294,8 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
             break;
 
         case WXK_RIGHT:
-            // this works the same as the down arrow except that we also expand the
-            // item if it wasn't expanded yet
+            // this works the same as the down arrow except that we
+            // also expand the item if it wasn't expanded yet
             Expand(m_current);
             // fall through
 
@@ -2277,11 +2361,15 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
         case WXK_HOME:
             {
                 wxTreeItemId prev = GetRootItem();
-                if (prev)
+                if (!prev) break;
+                if (HasFlag(wxTR_HIDE_ROOT))
                 {
-                    EnsureVisible( prev );
-                    SelectItem( prev, unselect_others, extended_select );
+                    long dummy;
+                    prev = GetFirstChild(prev, dummy);
+                    if (!prev) break;
                 }
+                EnsureVisible( prev );
+                SelectItem( prev, unselect_others, extended_select );
             }
             break;
 
@@ -2292,30 +2380,38 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
 
 wxTreeItemId wxGenericTreeCtrl::HitTest(const wxPoint& point, int& flags)
 {
-    // We have to call this here because the label in
-    // question might just have been added and no screen
-    // update taken place.
-    // JACS: removed this because the yield can cause the window to be
-    // deleted from under us if a close window event is pending
-    // if (m_dirty) wxYieldIfNeeded();
+    // JACS: removed wxYieldIfNeeded() because it can cause the window
+    // to be deleted from under us if a close window event is pending
 
-    wxClientDC dc(this);
-    PrepareDC(dc);
-    wxCoord x = dc.DeviceToLogicalX( point.x );
-    wxCoord y = dc.DeviceToLogicalY( point.y );
     int w, h;
     GetSize(&w, &h);
-
     flags=0;
-    if (point.x<0) flags|=wxTREE_HITTEST_TOLEFT;
-    if (point.x>w) flags|=wxTREE_HITTEST_TORIGHT;
-    if (point.y<0) flags|=wxTREE_HITTEST_ABOVE;
-    if (point.y>h) flags|=wxTREE_HITTEST_BELOW;
+    if (point.x<0) flags |= wxTREE_HITTEST_TOLEFT;
+    if (point.x>w) flags |= wxTREE_HITTEST_TORIGHT;
+    if (point.y<0) flags |= wxTREE_HITTEST_ABOVE;
+    if (point.y>h) flags |= wxTREE_HITTEST_BELOW;
+    if (flags) return wxTreeItemId();
 
-    if (m_anchor)
-        return m_anchor->HitTest( wxPoint(x, y), this, flags);
+    if (m_anchor == NULL)
+    {
+        flags = wxTREE_HITTEST_NOWHERE;
+        return wxTreeItemId();
+    }
 
-    return wxTreeItemId();
+    wxClientDC dc(this);
+    PrepareDC(dc);
+    wxCoord x = dc.DeviceToLogicalX( point.x );
+    wxCoord y = dc.DeviceToLogicalY( point.y );
+    wxGenericTreeItem *hit =  m_anchor->HitTest(wxPoint(x, y),
+                                                this,
+                                                flags,
+                                                0 );
+    if (hit == NULL)
+    {
+        flags = wxTREE_HITTEST_NOWHERE;
+        return wxTreeItemId();
+    }
+    return hit;
 }
 
 // get the bounding rectangle of the item (or of its label only)
@@ -2406,6 +2502,7 @@ void wxGenericTreeCtrl::OnRenameTimer()
 
 void wxGenericTreeCtrl::OnRenameAccept()
 {
+    // TODO if the validator fails this causes a crash
     wxTreeEvent le( wxEVT_COMMAND_TREE_END_LABEL_EDIT, GetId() );
     le.m_item = (long) m_currentEdit;
     le.SetEventObject( this );
@@ -2442,7 +2539,10 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
     wxCoord y = dc.DeviceToLogicalY( event.GetY() );
 
     int flags = 0;
-    wxGenericTreeItem *item = m_anchor->HitTest( wxPoint(x,y), this, flags);
+    wxGenericTreeItem *item = m_anchor->HitTest( wxPoint(x,y),
+                                                 this,
+                                                 flags,
+                                                 0 );
 
     if ( event.Dragging() && !m_isDragging )
     {
@@ -2603,20 +2703,32 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
 
             SelectItem(item, unselect_others, extended_select);
 
+            // For some reason, Windows isn't recognizing a left double-click,
+            // so we need to simulate it here.  Allow 200 milliseconds for now.
             if ( event.LeftDClick() )
             {
                 // double clicking should not start editing the item label
                 m_renameTimer->Stop();
                 m_lastOnSame = FALSE;
 
-                wxTreeEvent nevent( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, GetId() );
-                nevent.m_item = (long) item;
-                nevent.m_code = 0;
-                CalcScrolledPosition(x, y,
-                                     &nevent.m_pointDrag.x,
-                                     &nevent.m_pointDrag.y);
-                nevent.SetEventObject( this );
-                GetEventHandler()->ProcessEvent( nevent );
+                if (item->HasPlus())
+                {
+                    // for a "directory" node, toggle expansion
+                    Toggle(item);
+                }
+                else
+                {
+                    // for a "file" node, activate it
+                    wxTreeEvent nevent( wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
+                                        GetId() );
+                    nevent.m_item = (long) item;
+                    nevent.m_code = 0;
+                    CalcScrolledPosition(x, y,
+                                         &nevent.m_pointDrag.x,
+                                         &nevent.m_pointDrag.y);
+                    nevent.SetEventObject( this );
+                    GetEventHandler()->ProcessEvent( nevent );
+                }
             }
         }
     }
@@ -2627,8 +2739,7 @@ void wxGenericTreeCtrl::OnIdle( wxIdleEvent &WXUNUSED(event) )
     /* after all changes have been done to the tree control,
      * we actually redraw the tree when everything is over */
 
-    if (!m_dirty)
-        return;
+    if (!m_dirty) return;
 
     m_dirty = FALSE;
 
@@ -2665,7 +2776,7 @@ void wxGenericTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
 
     int total_h = (image_h > text_h) ? image_h : text_h;
 
-    if (total_h < 40)
+    if (total_h < 30)
         total_h += 2;            // at least 2 pixels
     else
         total_h += total_h/10;   // otherwise 10% extra spacing
@@ -2682,25 +2793,37 @@ void wxGenericTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
 // not the middle of it !
 void wxGenericTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &y )
 {
-    int horizX = level*m_indent;
+    int x = level*m_indent;
+    if (!HasFlag(wxTR_HIDE_ROOT))
+    {
+        x += m_indent;
+    }
+    else if (level == 0)
+    {
+        // a hidden root is not evaluated, but its
+        // children are always calculated
+        goto Recurse;
+    }
 
     CalculateSize( item, dc );
 
     // set its position
-    item->SetX( horizX+m_indent+m_spacing );
+    item->SetX( x+m_spacing );
     item->SetY( y );
-    y+=GetLineHeight(item);
+    y += GetLineHeight(item);
 
     if ( !item->IsExpanded() )
     {
-        // we dont need to calculate collapsed branches
+        // we don't need to calculate collapsed branches
         return;
     }
 
+  Recurse:
     wxArrayGenericTreeItems& children = item->GetChildren();
     size_t n, count = children.Count();
+    ++level;
     for (n = 0; n < count; ++n )
-        CalculateLevel( children[n], dc, level+1, y );  // recurse
+        CalculateLevel( children[n], dc, level, y );  // recurse
 }
 
 void wxGenericTreeCtrl::CalculatePositions()
index 78ca55abb0251f3c9aeb855391e015032e8d9836..2ca35f3f484e30f8a7be82bf6cb36b19196fb371 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "wx/html/helpfrm.h"
 #include "wx/html/helpctrl.h"
+#include "wx/textctrl.h"
 #include "wx/notebook.h"
 #include "wx/imaglist.h"
 #include "wx/treectrl.h"