]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/treectlg.cpp
first attempt for full screen implementation
[wxWidgets.git] / src / generic / treectlg.cpp
index e82b05d4e6855a616247384110136ae6c6d91579..4f7bb21448acad726a9b25367e3380767d483950 100644 (file)
 
 #include "wx/renderer.h"
 
+#ifdef __WXMAC__
+    #include "wx/mac/private.h"
+#endif
+
 // -----------------------------------------------------------------------------
 // array types
 // -----------------------------------------------------------------------------
 
 class WXDLLEXPORT wxGenericTreeItem;
 
-WX_DEFINE_EXPORTED_ARRAY_NO_PTR(wxGenericTreeItem *, wxArrayGenericTreeItems);
+WX_DEFINE_EXPORTED_ARRAY_PTR(wxGenericTreeItem *, wxArrayGenericTreeItems);
 
 // ----------------------------------------------------------------------------
 // constants
@@ -150,7 +154,7 @@ public:
     void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
     void SetData(wxTreeItemData *data) { m_data = data; }
 
-    void SetHasPlus(bool has = TRUE) { m_hasPlus = has; }
+    void SetHasPlus(bool has = true) { m_hasPlus = has; }
 
     void SetBold(bool bold) { m_isBold = bold; }
 
@@ -174,7 +178,7 @@ public:
     void DeleteChildren(wxGenericTreeCtrl *tree = NULL);
 
     // get count of all children (and grand children if 'recursively')
-    size_t GetChildrenCount(bool recursively = TRUE) const;
+    size_t GetChildrenCount(bool recursively = true) const;
 
     void Insert(wxGenericTreeItem *child, size_t index)
     { m_children.Insert(child, index); }
@@ -182,17 +186,17 @@ public:
     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
+        // true if the point belongs to the item's button, otherwise it lies
+        // on the item's label
     wxGenericTreeItem *HitTest( const wxPoint& point,
                                 const wxGenericTreeCtrl *,
                                 int &flags,
                                 int level );
 
-    void Expand() { m_isCollapsed = FALSE; }
-    void Collapse() { m_isCollapsed = TRUE; }
+    void Expand() { m_isCollapsed = false; }
+    void Collapse() { m_isCollapsed = true; }
 
-    void SetHilight( bool set = TRUE ) { m_hasHilight = set; }
+    void SetHilight( bool set = true ) { m_hasHilight = set; }
 
     // status inquiries
     bool HasChildren() const { return !m_children.IsEmpty(); }
@@ -210,7 +214,7 @@ public:
         if ( !m_attr )
         {
             m_attr = new wxTreeItemAttr;
-            m_ownsAttr = TRUE;
+            m_ownsAttr = true;
         }
         return *m_attr;
     }
@@ -219,13 +223,13 @@ public:
     {
         if ( m_ownsAttr ) delete m_attr;
         m_attr = attr;
-        m_ownsAttr = FALSE;
+        m_ownsAttr = false;
     }
         // set them and delete when done
     void AssignAttributes(wxTreeItemAttr *attr)
     {
         SetAttributes(attr);
-        m_ownsAttr = TRUE;
+        m_ownsAttr = true;
     }
 
 private:
@@ -291,13 +295,13 @@ static bool IsDescendantOf(wxGenericTreeItem *parent, wxGenericTreeItem *item)
         if ( item == parent )
         {
             // item is a descendant of parent
-            return TRUE;
+            return true;
         }
 
         item = item->GetParent();
     }
 
-    return FALSE;
+    return false;
 }
 
 // -----------------------------------------------------------------------------
@@ -329,7 +333,7 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner,
               : m_itemEdited(item), m_startValue(item->GetText())
 {
     m_owner = owner;
-    m_finished = FALSE;
+    m_finished = false;
 
     int w = m_itemEdited->GetWidth(),
         h = m_itemEdited->GetHeight();
@@ -369,19 +373,19 @@ bool wxTreeTextCtrl::AcceptChanges()
     if ( value == m_startValue )
     {
         // nothing changed, always accept
-        return TRUE;
+        return true;
     }
 
     if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
     {
         // vetoed by the user
-        return FALSE;
+        return false;
     }
 
     // accepted, do rename the item
     m_owner->SetItemText(m_itemEdited, value);
 
-    return TRUE;
+    return true;
 }
 
 void wxTreeTextCtrl::Finish()
@@ -392,7 +396,7 @@ void wxTreeTextCtrl::Finish()
 
         wxPendingDelete.Append(this);
 
-        m_finished = TRUE;
+        m_finished = true;
 
         m_owner->SetFocus(); // This doesn't work. TODO.
     }
@@ -403,12 +407,14 @@ void wxTreeTextCtrl::OnChar( wxKeyEvent &event )
     switch ( event.m_keyCode )
     {
         case WXK_RETURN:
-            if ( !AcceptChanges() )
+            if ( AcceptChanges() )
             {
-                // vetoed by the user, don't disappear
-                break;
+                // Close the text control, changes were accepted
+                Finish();
             }
-            //else: fall through
+            // else do nothing, do not accept and do not close
+
+            break;
 
         case WXK_ESCAPE:
             Finish();
@@ -434,7 +440,7 @@ void wxTreeTextCtrl::OnKeyUp( wxKeyEvent &event )
             sx = parentSize.x - myPos.x;
         if (mySize.x > sx)
             sx = mySize.x;
-        SetSize(sx, -1);
+        SetSize(sx, wxDefaultCoord);
     }
 
     event.Skip();
@@ -472,15 +478,15 @@ wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent,
     m_data = data;
     m_x = m_y = 0;
 
-    m_isCollapsed = TRUE;
-    m_hasHilight = FALSE;
-    m_hasPlus = FALSE;
-    m_isBold = FALSE;
+    m_isCollapsed = true;
+    m_hasHilight = false;
+    m_hasPlus = false;
+    m_isBold = false;
 
     m_parent = parent;
 
     m_attr = (wxTreeItemAttr *)NULL;
-    m_ownsAttr = FALSE;
+    m_ownsAttr = false;
 
     // We don't know the height here yet.
     m_width = 0;
@@ -578,8 +584,8 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point,
                 HasPlus() && theCtrl->HasButtons() )
 #else
             // 5 is the size of the plus sign
-            if ((point.x > xCross-5) && (point.x < xCross+5) &&
-                (point.y > y_mid-5) && (point.y < y_mid+5) &&
+            if ((point.x > xCross-6) && (point.x < xCross+6) &&
+                (point.y > y_mid-6) && (point.y < y_mid+6) &&
                 HasPlus() && theCtrl->HasButtons() )
 #endif
             {
@@ -674,9 +680,10 @@ BEGIN_EVENT_TABLE(wxGenericTreeCtrl,wxScrolledWindow)
     EVT_CHAR           (wxGenericTreeCtrl::OnChar)
     EVT_SET_FOCUS      (wxGenericTreeCtrl::OnSetFocus)
     EVT_KILL_FOCUS     (wxGenericTreeCtrl::OnKillFocus)
+    EVT_TREE_ITEM_GETTOOLTIP(wxID_ANY, wxGenericTreeCtrl::OnGetToolTip)
 END_EVENT_TABLE()
 
-#if !defined(__WXMSW__) || defined(__WIN16__) || defined(__WXUNIVERSAL__)
+#if !defined(__WXMSW__) || defined(__WXUNIVERSAL__)
 /*
  * wxTreeCtrl has to be a real class or we have problems with
  * the run-time information.
@@ -692,8 +699,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxGenericTreeCtrl)
 void wxGenericTreeCtrl::Init()
 {
     m_current = m_key_current = m_anchor = m_select_me = (wxGenericTreeItem *) NULL;
-    m_hasFocus = FALSE;
-    m_dirty = FALSE;
+    m_hasFocus = false;
+    m_dirty = false;
 
     m_lineHeight = 10;
     m_indent = 15;
@@ -720,19 +727,26 @@ void wxGenericTreeCtrl::Init()
     m_imageListNormal = m_imageListButtons =
     m_imageListState = (wxImageList *) NULL;
     m_ownsImageListNormal = m_ownsImageListButtons =
-    m_ownsImageListState = FALSE;
+    m_ownsImageListState = false;
 
     m_dragCount = 0;
-    m_isDragging = FALSE;
-    m_dropTarget = m_oldSelection = (wxGenericTreeItem *)NULL;
+    m_isDragging = false;
+    m_dropTarget = m_oldSelection = NULL;
+    m_underMouse = NULL;
     m_textCtrl = NULL;
 
     m_renameTimer = NULL;
+    m_freezeCount = 0;
+
     m_findTimer = NULL;
 
-    m_lastOnSame = FALSE;
+    m_lastOnSame = false;
 
+#if defined( __WXMAC__ ) && __WXMAC_CARBON__
+    m_normalFont.MacCreateThemeFont( kThemeViewsFont ) ;
+#else
     m_normalFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
+#endif
     m_boldFont = wxFont(m_normalFont.GetPointSize(),
                         m_normalFont.GetFamily(),
                         m_normalFont.GetStyle(),
@@ -747,7 +761,7 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent,
                                const wxPoint& pos,
                                const wxSize& size,
                                long style,
-                               const wxValidator &validator,
+                               const wxValidator& wxVALIDATOR_PARAM(validator),
                                const wxString& name )
 {
 #ifdef __WXMAC__
@@ -776,13 +790,18 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent,
     SetValidator( validator );
 #endif
 
-    SetForegroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) );
-    SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX) );
+    wxVisualAttributes attr = GetDefaultAttributes();
+    SetOwnForegroundColour( attr.colFg );
+    SetOwnBackgroundColour( attr.colBg );
+    if (!m_hasFont)
+        SetOwnFont(attr.font);
 
 //  m_dottedPen = wxPen( "grey", 0, wxDOT );  too slow under XFree86
     m_dottedPen = wxPen( wxT("grey"), 0, 0 );
 
-    return TRUE;
+    SetBestSize(size);
+
+    return true;
 }
 
 wxGenericTreeCtrl::~wxGenericTreeCtrl()
@@ -809,22 +828,37 @@ wxGenericTreeCtrl::~wxGenericTreeCtrl()
 
 size_t wxGenericTreeCtrl::GetCount() const
 {
-    return m_anchor == NULL ? 0u : m_anchor->GetChildrenCount();
+    if ( !m_anchor )
+    {
+        // the tree is empty
+        return 0;
+    }
+
+    size_t count = m_anchor->GetChildrenCount();
+    if ( !HasFlag(wxTR_HIDE_ROOT) )
+    {
+        // take the root itself into account
+        count++;
+    }
+
+    return count;
 }
 
 void wxGenericTreeCtrl::SetIndent(unsigned int indent)
 {
     m_indent = (unsigned short) indent;
-    m_dirty = TRUE;
+    m_dirty = true;
 }
 
 void wxGenericTreeCtrl::SetSpacing(unsigned int spacing)
 {
     m_spacing = (unsigned short) spacing;
-    m_dirty = TRUE;
+    m_dirty = true;
 }
 
-size_t wxGenericTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively)
+size_t
+wxGenericTreeCtrl::GetChildrenCount(const wxTreeItemId& item,
+                                    bool recursively) const
 {
     wxCHECK_MSG( item.IsOk(), 0u, wxT("invalid tree item") );
 
@@ -845,7 +879,7 @@ void wxGenericTreeCtrl::SetWindowStyle(const long styles)
     // want to update the inherited styles, but right now
     // none of the parents has updatable styles
     m_windowStyle = styles;
-    m_dirty = TRUE;
+    m_dirty = true;
 }
 
 // -----------------------------------------------------------------------------
@@ -927,6 +961,9 @@ void wxGenericTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *da
 {
     wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
 
+    if (data)
+        data->SetId( item );
+
     ((wxGenericTreeItem*) item.m_pItem)->SetData(data);
 }
 
@@ -994,7 +1031,7 @@ bool wxGenericTreeCtrl::SetFont( const wxFont &font )
                         m_normalFont.GetFaceName(),
                         m_normalFont.GetEncoding());
 
-    return TRUE;
+    return true;
 }
 
 
@@ -1004,7 +1041,7 @@ bool wxGenericTreeCtrl::SetFont( const wxFont &font )
 
 bool wxGenericTreeCtrl::IsVisible(const wxTreeItemId& item) const
 {
-    wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
 
     // An item is only visible if it's not a descendant of a collapsed item
     wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
@@ -1012,7 +1049,7 @@ bool wxGenericTreeCtrl::IsVisible(const wxTreeItemId& item) const
     while (parent)
     {
         if (!parent->IsExpanded())
-            return FALSE;
+            return false;
         parent = parent->GetParent();
     }
 
@@ -1023,20 +1060,20 @@ bool wxGenericTreeCtrl::IsVisible(const wxTreeItemId& item) const
 
     wxRect rect;
     if (!GetBoundingRect(item, rect))
-        return FALSE;
+        return false;
     if (rect.GetWidth() == 0 || rect.GetHeight() == 0)
-        return FALSE;
+        return false;
     if (rect.GetBottom() < 0 || rect.GetTop() > clientSize.y)
-        return FALSE;
+        return false;
     if (rect.GetRight() < 0 || rect.GetLeft() > clientSize.x)
-        return FALSE;
+        return false;
 
-    return TRUE;
+    return true;
 }
 
 bool wxGenericTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const
 {
-    wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
 
     // consider that the item does have children if it has the "+" button: it
     // might not have them (if it had never been expanded yet) but then it
@@ -1048,21 +1085,21 @@ bool wxGenericTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const
 
 bool wxGenericTreeCtrl::IsExpanded(const wxTreeItemId& item) const
 {
-    wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
 
     return ((wxGenericTreeItem*) item.m_pItem)->IsExpanded();
 }
 
 bool wxGenericTreeCtrl::IsSelected(const wxTreeItemId& item) const
 {
-    wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
 
     return ((wxGenericTreeItem*) item.m_pItem)->IsSelected();
 }
 
 bool wxGenericTreeCtrl::IsBold(const wxTreeItemId& item) const
 {
-    wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
 
     return ((wxGenericTreeItem*) item.m_pItem)->IsBold();
 }
@@ -1323,7 +1360,7 @@ 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
+    m_dirty = true;     // do this first so stuff below doesn't cause flicker
 
     wxGenericTreeItem *item =
         new wxGenericTreeItem( parent, text, image, selImage, data );
@@ -1344,7 +1381,7 @@ 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
+    m_dirty = true;     // do this first so stuff below doesn't cause flicker
 
     m_anchor = new wxGenericTreeItem((wxGenericTreeItem *)NULL, text,
                                    image, selImage, data);
@@ -1365,7 +1402,7 @@ wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text,
     if (!HasFlag(wxTR_MULTIPLE))
     {
         m_current = m_key_current = m_anchor;
-        m_current->SetHilight( TRUE );
+        m_current->SetHilight( true );
     }
 
     return m_anchor;
@@ -1445,7 +1482,7 @@ void wxGenericTreeCtrl::SendDeleteEvent(wxGenericTreeItem *item)
 
 void wxGenericTreeCtrl::DeleteChildren(const wxTreeItemId& itemId)
 {
-    m_dirty = TRUE;     // do this first so stuff below doesn't cause flicker
+    m_dirty = true;     // do this first so stuff below doesn't cause flicker
 
     wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
     item->DeleteChildren(this);
@@ -1453,7 +1490,7 @@ void wxGenericTreeCtrl::DeleteChildren(const wxTreeItemId& itemId)
 
 void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
 {
-    m_dirty = TRUE;     // do this first so stuff below doesn't cause flicker
+    m_dirty = true;     // do this first so stuff below doesn't cause flicker
 
     wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
 
@@ -1465,7 +1502,7 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
         // Don't silently change the selection:
         // do it properly in idle time, so event
         // handlers get called.
-        
+
         // m_key_current = parent;
         m_key_current = NULL;
     }
@@ -1482,7 +1519,7 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
         // Don't silently change the selection:
         // do it properly in idle time, so event
         // handlers get called.
-        
+
         // m_current = parent;
         m_current = NULL;
         m_select_me = parent;
@@ -1623,7 +1660,7 @@ void wxGenericTreeCtrl::Unselect()
 {
     if (m_current)
     {
-        m_current->SetHilight( FALSE );
+        m_current->SetHilight( false );
         RefreshLine( m_current );
 
         m_current = NULL;
@@ -1635,7 +1672,7 @@ void wxGenericTreeCtrl::UnselectAllChildren(wxGenericTreeItem *item)
 {
     if (item->IsSelected())
     {
-        item->SetHilight(FALSE);
+        item->SetHilight(false);
         RefreshLine(item);
     }
 
@@ -1681,7 +1718,7 @@ bool wxGenericTreeCtrl::TagNextChildren(wxGenericTreeItem *crt_item, wxGenericTr
     size_t count = children.Count();
     for (size_t n=(size_t)(index+1); n<count; ++n)
     {
-        if (TagAllChildrenUntilLast(children[n], last_item, select)) return TRUE;
+        if (TagAllChildrenUntilLast(children[n], last_item, select)) return true;
     }
 
     return TagNextChildren(parent, last_item, select);
@@ -1693,7 +1730,7 @@ bool wxGenericTreeCtrl::TagAllChildrenUntilLast(wxGenericTreeItem *crt_item, wxG
     RefreshLine(crt_item);
 
     if (crt_item==last_item)
-        return TRUE;
+        return true;
 
     if (crt_item->HasChildren())
     {
@@ -1702,30 +1739,21 @@ bool wxGenericTreeCtrl::TagAllChildrenUntilLast(wxGenericTreeItem *crt_item, wxG
         for ( size_t n = 0; n < count; ++n )
         {
             if (TagAllChildrenUntilLast(children[n], last_item, select))
-                return TRUE;
+                return true;
         }
     }
 
-  return FALSE;
+  return false;
 }
 
 void wxGenericTreeCtrl::SelectItemRange(wxGenericTreeItem *item1, wxGenericTreeItem *item2)
 {
-    // item2 is not necessary after item1
-    wxGenericTreeItem *first=NULL, *last=NULL;
     m_select_me = NULL;
 
+    // item2 is not necessary after item1
     // choice first' and 'last' between item1 and item2
-    if (item1->GetY()<item2->GetY())
-    {
-        first=item1;
-        last=item2;
-    }
-    else
-    {
-        first=item2;
-        last=item1;
-    }
+    wxGenericTreeItem *first= (item1->GetY()<item2->GetY()) ? item1 : item2;
+    wxGenericTreeItem *last = (item1->GetY()<item2->GetY()) ? item2 : item1;
 
     bool select = m_current->IsSelected();
 
@@ -1735,14 +1763,14 @@ void wxGenericTreeCtrl::SelectItemRange(wxGenericTreeItem *item1, wxGenericTreeI
     TagNextChildren(first,last,select);
 }
 
-void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId,
-                                   bool unselect_others,
-                                   bool extended_select)
+void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId,
+                                     bool unselect_others,
+                                     bool extended_select)
 {
     wxCHECK_RET( itemId.IsOk(), wxT("invalid tree item") );
 
     m_select_me = NULL;
-    
+
     bool is_single=!(GetWindowStyleFlag() & wxTR_MULTIPLE);
     wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
 
@@ -1754,8 +1782,8 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId,
     {
         if (item->IsSelected())
             return; // nothing to do
-        unselect_others = TRUE;
-        extended_select = FALSE;
+        unselect_others = true;
+        extended_select = false;
     }
     else if ( unselect_others && item->IsSelected() )
     {
@@ -1805,7 +1833,7 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId,
     }
     else
     {
-        bool select=TRUE; // the default
+        bool select = true; // the default
 
         // Check if we need to toggle hilight (ctrl mode)
         if (!unselect_others)
@@ -1820,6 +1848,22 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId,
     GetEventHandler()->ProcessEvent( event );
 }
 
+void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, bool select)
+{
+    if ( select )
+    {
+        DoSelectItem(itemId);
+    }
+    else // deselect
+    {
+        wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
+        wxCHECK_RET( item, wxT("SelectItem(): invalid tree item") );
+
+        item->SetHilight(false);
+        RefreshLine(item);
+    }
+}
+
 void wxGenericTreeCtrl::FillArray(wxGenericTreeItem *item,
                                   wxArrayTreeItemIds &array) const
 {
@@ -1850,6 +1894,8 @@ size_t wxGenericTreeCtrl::GetSelections(wxArrayTreeItemIds &array) const
 
 void wxGenericTreeCtrl::EnsureVisible(const wxTreeItemId& item)
 {
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
     if (!item.IsOk()) return;
 
     wxGenericTreeItem *gitem = (wxGenericTreeItem*) item.m_pItem;
@@ -1886,8 +1932,12 @@ void wxGenericTreeCtrl::ScrollTo(const wxTreeItemId &item)
     // We have to call this here because the label in
     // question might just have been added and no screen
     // update taken place.
-    if (m_dirty) wxYieldIfNeeded();
-
+    if (m_dirty)
+#if defined( __WXMSW__ ) || defined(__WXMAC__)
+        Update();
+#else
+        wxYieldIfNeeded();
+#endif
     wxGenericTreeItem *gitem = (wxGenericTreeItem*) item.m_pItem;
 
     // now scroll to the item
@@ -1958,7 +2008,7 @@ void wxGenericTreeCtrl::SortChildren(const wxTreeItemId& itemId)
     wxArrayGenericTreeItems& children = item->GetChildren();
     if ( children.Count() > 1 )
     {
-        m_dirty = TRUE;
+        m_dirty = true;
 
         s_treeBeingSorted = this;
         children.Sort(tree_ctrl_compare_func);
@@ -2025,8 +2075,8 @@ void wxGenericTreeCtrl::SetImageList(wxImageList *imageList)
 {
     if (m_ownsImageListNormal) delete m_imageListNormal;
     m_imageListNormal = imageList;
-    m_ownsImageListNormal = FALSE;
-    m_dirty = TRUE;
+    m_ownsImageListNormal = false;
+    m_dirty = true;
     // Don't do any drawing if we're setting the list to NULL,
     // since we may be in the process of deleting the tree control.
     if (imageList)
@@ -2037,34 +2087,34 @@ void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList)
 {
     if (m_ownsImageListState) delete m_imageListState;
     m_imageListState = imageList;
-    m_ownsImageListState = FALSE;
+    m_ownsImageListState = false;
 }
 
 void wxGenericTreeCtrl::SetButtonsImageList(wxImageList *imageList)
 {
     if (m_ownsImageListButtons) delete m_imageListButtons;
     m_imageListButtons = imageList;
-    m_ownsImageListButtons = FALSE;
-    m_dirty = TRUE;
+    m_ownsImageListButtons = false;
+    m_dirty = true;
     CalculateLineHeight();
 }
 
 void wxGenericTreeCtrl::AssignImageList(wxImageList *imageList)
 {
     SetImageList(imageList);
-    m_ownsImageListNormal = TRUE;
+    m_ownsImageListNormal = true;
 }
 
 void wxGenericTreeCtrl::AssignStateImageList(wxImageList *imageList)
 {
     SetStateImageList(imageList);
-    m_ownsImageListState = TRUE;
+    m_ownsImageListState = true;
 }
 
 void wxGenericTreeCtrl::AssignButtonsImageList(wxImageList *imageList)
 {
     SetButtonsImageList(imageList);
-    m_ownsImageListButtons = TRUE;
+    m_ownsImageListButtons = true;
 }
 
 // -----------------------------------------------------------------------------
@@ -2328,6 +2378,12 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
                 static const int wImage = 9;
                 static const int hImage = 9;
 
+                int flag = 0;
+                if (item->IsExpanded())
+                    flag |= wxCONTROL_EXPANDED;
+                if (item == m_underMouse)
+                    flag |= wxCONTROL_CURRENT;
+
                 wxRendererNative::Get().DrawTreeItemButton
                                         (
                                             this,
@@ -2335,9 +2391,7 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
                                             wxRect(x - wImage/2,
                                                    y_mid - hImage/2,
                                                    wImage, hImage),
-                                            item->IsExpanded()
-                                                ? wxCONTROL_EXPANDED
-                                                : 0
+                                            flag
                                         );
             }
         }
@@ -2363,7 +2417,7 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
                 if (HasButtons()) y_mid += 5;
 
                 // Only draw the portion of the line that is visible, in case it is huge
-                wxCoord        xOrigin=0, yOrigin=0, width, height;
+                wxCoord xOrigin=0, yOrigin=0, width, height;
                 dc.GetDeviceOrigin(&xOrigin, &yOrigin);
                 yOrigin = abs(yOrigin);
                 GetClientSize(&width, &height);
@@ -2396,7 +2450,7 @@ void wxGenericTreeCtrl::DrawDropEffect(wxGenericTreeItem *item)
         {
             // draw a line under the drop target because the item will be
             // dropped there
-            DrawLine(item, TRUE /* below */);
+            DrawLine(item, true /* below */);
         }
 
         SetCursor(wxCURSOR_BULLSEYE);
@@ -2446,7 +2500,7 @@ void wxGenericTreeCtrl::DrawLine(const wxTreeItemId &item, bool below)
 }
 
 // -----------------------------------------------------------------------------
-// wxWindows callbacks
+// wxWidgets callbacks
 // -----------------------------------------------------------------------------
 
 void wxGenericTreeCtrl::OnPaint( wxPaintEvent &WXUNUSED(event) )
@@ -2470,7 +2524,7 @@ void wxGenericTreeCtrl::OnPaint( wxPaintEvent &WXUNUSED(event) )
 
 void wxGenericTreeCtrl::OnSetFocus( wxFocusEvent &event )
 {
-    m_hasFocus = TRUE;
+    m_hasFocus = true;
 
     RefreshSelected();
 
@@ -2479,7 +2533,7 @@ void wxGenericTreeCtrl::OnSetFocus( wxFocusEvent &event )
 
 void wxGenericTreeCtrl::OnKillFocus( wxFocusEvent &event )
 {
-    m_hasFocus = FALSE;
+    m_hasFocus = false;
 
     RefreshSelected();
 
@@ -2588,7 +2642,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
                         if (current == GetFirstChild( prev, cookie ))
                         {
                             // otherwise we return to where we came from
-                            SelectItem( prev, unselect_others, extended_select );
+                            DoSelectItem( prev, unselect_others, extended_select );
                             m_key_current= (wxGenericTreeItem*) prev.m_pItem;
                             break;
                         }
@@ -2605,7 +2659,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
                         }
                     }
 
-                    SelectItem( prev, unselect_others, extended_select );
+                    DoSelectItem( prev, unselect_others, extended_select );
                     m_key_current=(wxGenericTreeItem*) prev.m_pItem;
                 }
             }
@@ -2622,7 +2676,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
                 }
                 if (prev)
                 {
-                    SelectItem( prev, unselect_others, extended_select );
+                    DoSelectItem( prev, unselect_others, extended_select );
                 }
             }
             break;
@@ -2639,7 +2693,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
                 {
                     wxTreeItemIdValue cookie;
                     wxTreeItemId child = GetFirstChild( m_key_current, cookie );
-                    SelectItem( child, unselect_others, extended_select );
+                    DoSelectItem( child, unselect_others, extended_select );
                     m_key_current=(wxGenericTreeItem*) child.m_pItem;
                 }
                 else
@@ -2656,7 +2710,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
                     }
                     if (next)
                     {
-                        SelectItem( next, unselect_others, extended_select );
+                        DoSelectItem( next, unselect_others, extended_select );
                         m_key_current=(wxGenericTreeItem*) next.m_pItem;
                     }
                 }
@@ -2674,7 +2728,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
 
                     // it may happen if the item was expanded but then all of
                     // its children have been deleted - so IsExpanded() returned
-                    // TRUE, but GetLastChild() returned invalid item
+                    // true, but GetLastChild() returned invalid item
                     if ( !lastChild )
                         break;
 
@@ -2683,7 +2737,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
 
                 if ( last.IsOk() )
                 {
-                    SelectItem( last, unselect_others, extended_select );
+                    DoSelectItem( last, unselect_others, extended_select );
                 }
             }
             break;
@@ -2703,7 +2757,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
                         break;
                 }
 
-                SelectItem( prev, unselect_others, extended_select );
+                DoSelectItem( prev, unselect_others, extended_select );
             }
             break;
 
@@ -2715,9 +2769,9 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
                   (keyCode >= 'A' && keyCode <= 'Z' )))
             {
                 // find the next item starting with the given prefix
-                char ch = (char)keyCode;
+                wxChar ch = (wxChar)keyCode;
 
-                wxTreeItemId id = FindItem(m_current, m_findPrefix + (wxChar)ch);
+                wxTreeItemId id = FindItem(m_current, m_findPrefix + ch);
                 if ( !id.IsOk() )
                 {
                     // no such item
@@ -2780,7 +2834,7 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item,
                                         wxRect& rect,
                                         bool WXUNUSED(textOnly)) const
 {
-    wxCHECK_MSG( item.IsOk(), FALSE, _T("invalid item in wxGenericTreeCtrl::GetBoundingRect") );
+    wxCHECK_MSG( item.IsOk(), false, _T("invalid item in wxGenericTreeCtrl::GetBoundingRect") );
 
     wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
 
@@ -2793,7 +2847,7 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item,
     //rect.height = i->GetHeight();
     rect.height = GetLineHeight(i);
 
-    return TRUE;
+    return true;
 }
 
 void wxGenericTreeCtrl::Edit( const wxTreeItemId& item )
@@ -2815,7 +2869,11 @@ void wxGenericTreeCtrl::Edit( const wxTreeItemId& item )
     // question might just have been added and no screen
     // update taken place.
     if ( m_dirty )
+#if defined( __WXMSW__ ) || defined(__WXMAC__)
+        Update();
+#else
         wxYieldIfNeeded();
+#endif
 
     m_textCtrl = new wxTreeTextCtrl(this, itemEdit);
 
@@ -2837,7 +2895,7 @@ bool wxGenericTreeCtrl::OnRenameAccept(wxGenericTreeItem *item,
     le.m_item = item;
     le.SetEventObject( this );
     le.m_label = value;
-    le.m_editCancelled = FALSE;
+    le.m_editCancelled = false;
 
     return !GetEventHandler()->ProcessEvent( le ) || le.IsAllowed();
 }
@@ -2849,7 +2907,7 @@ void wxGenericTreeCtrl::OnRenameCancelled(wxGenericTreeItem *item)
     le.m_item = item;
     le.SetEventObject( this );
     le.m_label = wxEmptyString;
-    le.m_editCancelled = TRUE;
+    le.m_editCancelled = true;
 
     GetEventHandler()->ProcessEvent( le );
 }
@@ -2866,6 +2924,62 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
 {
     if ( !m_anchor ) return;
 
+    wxPoint pt = CalcUnscrolledPosition(event.GetPosition());
+
+    // Is the mouse over a tree item button?
+    int flags = 0;
+    wxGenericTreeItem *thisItem = m_anchor->HitTest(pt, this, flags, 0);
+    wxGenericTreeItem *underMouse = thisItem;
+#if wxUSE_TOOLTIPS
+    bool underMouseChanged = (underMouse != m_underMouse) ;
+#endif // wxUSE_TOOLTIPS
+
+    if ((underMouse) &&
+        (flags & wxTREE_HITTEST_ONITEMBUTTON) &&
+        (!event.LeftIsDown()) &&
+        (!m_isDragging) &&
+        (!m_renameTimer || !m_renameTimer->IsRunning()))
+    {
+    }
+    else
+    {
+        underMouse = NULL;
+    }
+
+    if (underMouse != m_underMouse)
+    {
+         if (m_underMouse)
+         {
+            // unhighlight old item
+            wxGenericTreeItem *tmp = m_underMouse;
+            m_underMouse = NULL;
+            RefreshLine( tmp );
+         }
+
+         m_underMouse = underMouse;
+         if (m_underMouse)
+            RefreshLine( m_underMouse );
+    }
+
+#if wxUSE_TOOLTIPS
+    // Determines what item we are hovering over and need a tooltip for
+    wxTreeItemId hoverItem = thisItem;
+
+    // We do not want a tooltip if we are dragging, or if the rename timer is running
+    if (underMouseChanged && hoverItem.IsOk() && !m_isDragging && (!m_renameTimer || !m_renameTimer->IsRunning()))
+    {
+        // Ask the tree control what tooltip (if any) should be shown
+        wxTreeEvent hevent(wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, GetId());
+        hevent.m_item = hoverItem;
+        hevent.SetEventObject(this);
+
+        if ( GetEventHandler()->ProcessEvent(hevent) && hevent.IsAllowed() )
+        {
+            SetToolTip(hevent.m_label);
+        }
+    }
+#endif
+
     // we process left mouse up event (enables in-place edit), right down
     // (pass to the user code), left dbl click (activate item) and
     // dragging/moving events for items drag-and-drop
@@ -2881,9 +2995,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
         return;
     }
 
-    wxPoint pt = CalcUnscrolledPosition(event.GetPosition());
 
-    int flags = 0;
+    flags = 0;
     wxGenericTreeItem *item = m_anchor->HitTest(pt, this, flags, 0);
 
     if ( event.Dragging() && !m_isDragging )
@@ -2914,7 +3027,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
         if ( GetEventHandler()->ProcessEvent(nevent) && nevent.IsAllowed() )
         {
             // we're going to drag this item
-            m_isDragging = TRUE;
+            m_isDragging = true;
 
             // remember the old cursor because we will change it while
             // dragging
@@ -2927,7 +3040,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
 
                 if ( m_oldSelection )
                 {
-                    m_oldSelection->SetHilight(FALSE);
+                    m_oldSelection->SetHilight(false);
                     RefreshLine(m_oldSelection);
                 }
             }
@@ -2947,7 +3060,11 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
             // highlight the current drop target if any
             DrawDropEffect(m_dropTarget);
 
+#if defined( __WXMSW__ ) || defined(__WXMAC__)
+            Update();
+#else
             wxYieldIfNeeded();
+#endif
         }
     }
     else if ( (event.LeftUp() || event.RightUp()) && m_isDragging )
@@ -2957,7 +3074,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
 
         if ( m_oldSelection )
         {
-            m_oldSelection->SetHilight(TRUE);
+            m_oldSelection->SetHilight(true);
             RefreshLine(m_oldSelection);
             m_oldSelection = (wxGenericTreeItem *)NULL;
         }
@@ -2971,14 +3088,18 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
 
         (void)GetEventHandler()->ProcessEvent(event);
 
-        m_isDragging = FALSE;
+        m_isDragging = false;
         m_dropTarget = (wxGenericTreeItem *)NULL;
 
         ReleaseMouse();
 
         SetCursor(m_oldCursor);
 
+#if defined( __WXMSW__ ) || defined(__WXMAC__)
+        Update();
+#else
         wxYieldIfNeeded();
+#endif
     }
     else
     {
@@ -3009,7 +3130,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
                     !event.ControlDown() &&
                     !event.ShiftDown())
                 {
-                    SelectItem(item, true, false);
+                    DoSelectItem(item, true, false);
                 }
             }
 
@@ -3029,10 +3150,10 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
                         m_renameTimer = new wxTreeRenameTimer( this );
                     }
 
-                    m_renameTimer->Start( wxTreeRenameTimer::DELAY, TRUE );
+                    m_renameTimer->Start( wxTreeRenameTimer::DELAY, true );
                 }
 
-                m_lastOnSame = FALSE;
+                m_lastOnSame = false;
             }
         }
         else // !RightDown() && !LeftUp() ==> LeftDown() || LeftDClick()
@@ -3070,7 +3191,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
                                     event.ControlDown(),
                                     is_multiple, extended_select, unselect_others);
 
-                SelectItem(item, unselect_others, extended_select);
+                DoSelectItem(item, unselect_others, extended_select);
             }
 
 
@@ -3082,7 +3203,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
                 if ( m_renameTimer )
                     m_renameTimer->Stop();
 
-                m_lastOnSame = FALSE;
+                m_lastOnSame = false;
 
                 // send activate event first
                 wxTreeEvent nevent( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, GetId() );
@@ -3107,7 +3228,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
 void wxGenericTreeCtrl::OnInternalIdle()
 {
     wxWindow::OnInternalIdle();
-    
+
     // Check if we need to select the root item
     // because nothing else has been selected.
     // Delaying it means that we can invoke event handlers
@@ -3124,8 +3245,9 @@ void wxGenericTreeCtrl::OnInternalIdle()
      * we actually redraw the tree when everything is over */
 
     if (!m_dirty) return;
+    if (m_freezeCount) return;
 
-    m_dirty = FALSE;
+    m_dirty = false;
 
     CalculatePositions();
     Refresh();
@@ -3142,6 +3264,8 @@ void wxGenericTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
         dc.SetFont(attr->GetFont());
     else if ( item->IsBold() )
         dc.SetFont(m_boldFont);
+    else
+        dc.SetFont(m_normalFont);
 
     dc.GetTextExtent( item->GetText(), &text_w, &text_h );
     text_h+=2;
@@ -3233,6 +3357,7 @@ void wxGenericTreeCtrl::CalculatePositions()
 void wxGenericTreeCtrl::RefreshSubtree(wxGenericTreeItem *item)
 {
     if (m_dirty) return;
+    if (m_freezeCount) return;
 
     wxSize client = GetClientSize();
 
@@ -3241,7 +3366,7 @@ void wxGenericTreeCtrl::RefreshSubtree(wxGenericTreeItem *item)
     rect.width = client.x;
     rect.height = client.y;
 
-    Refresh(TRUE, &rect);
+    Refresh(true, &rect);
 
     AdjustMyScrollbars();
 }
@@ -3249,17 +3374,20 @@ void wxGenericTreeCtrl::RefreshSubtree(wxGenericTreeItem *item)
 void wxGenericTreeCtrl::RefreshLine( wxGenericTreeItem *item )
 {
     if (m_dirty) return;
+    if (m_freezeCount) return;
 
     wxRect rect;
     CalcScrolledPosition(0, item->GetY(), NULL, &rect.y);
     rect.width = GetClientSize().x;
     rect.height = GetLineHeight(item); //dc.GetCharHeight() + 6;
 
-    Refresh(TRUE, &rect);
+    Refresh(true, &rect);
 }
 
 void wxGenericTreeCtrl::RefreshSelected()
 {
+    if (m_freezeCount) return;
+
     // TODO: this is awfully inefficient, we should keep the list of all
     //       selected items internally, should be much faster
     if ( m_anchor )
@@ -3268,6 +3396,8 @@ void wxGenericTreeCtrl::RefreshSelected()
 
 void wxGenericTreeCtrl::RefreshSelectedUnder(wxGenericTreeItem *item)
 {
+    if (m_freezeCount) return;
+
     if ( item->IsSelected() )
         RefreshLine(item);
 
@@ -3279,6 +3409,21 @@ void wxGenericTreeCtrl::RefreshSelectedUnder(wxGenericTreeItem *item)
     }
 }
 
+void wxGenericTreeCtrl::Freeze()
+{
+    m_freezeCount++;
+}
+
+void wxGenericTreeCtrl::Thaw()
+{
+    wxCHECK_RET( m_freezeCount > 0, _T("thawing unfrozen tree control?") );
+
+    if ( !--m_freezeCount )
+    {
+        Refresh();
+    }
+}
+
 // ----------------------------------------------------------------------------
 // changing colours: we need to refresh the tree control
 // ----------------------------------------------------------------------------
@@ -3286,21 +3431,61 @@ void wxGenericTreeCtrl::RefreshSelectedUnder(wxGenericTreeItem *item)
 bool wxGenericTreeCtrl::SetBackgroundColour(const wxColour& colour)
 {
     if ( !wxWindow::SetBackgroundColour(colour) )
-        return FALSE;
+        return false;
+
+    if (m_freezeCount) return true;
 
     Refresh();
 
-    return TRUE;
+    return true;
 }
 
 bool wxGenericTreeCtrl::SetForegroundColour(const wxColour& colour)
 {
     if ( !wxWindow::SetForegroundColour(colour) )
-        return FALSE;
+        return false;
+
+    if (m_freezeCount) return true;
 
     Refresh();
 
-    return TRUE;
+    return true;
+}
+
+// Process the tooltip event, to speed up event processing.
+// Doesn't actually get a tooltip.
+void wxGenericTreeCtrl::OnGetToolTip( wxTreeEvent &event )
+{
+    event.Veto();
+}
+
+
+// NOTE: If using the wxListBox visual attributes works everywhere then this can
+// be removed, as well as the #else case below.
+#define _USE_VISATTR 0
+
+#if _USE_VISATTR
+#include "wx/listbox.h"
+#endif
+
+//static
+wxVisualAttributes
+#if _USE_VISATTR
+wxGenericTreeCtrl::GetClassDefaultAttributes(wxWindowVariant variant)
+#else
+wxGenericTreeCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
+#endif
+{
+#if _USE_VISATTR
+    // Use the same color scheme as wxListBox
+    return wxListBox::GetClassDefaultAttributes(variant);
+#else
+    wxVisualAttributes attr;
+    attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+    attr.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX);
+    attr.font  = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+    return attr;
+#endif
 }
 
 #endif // wxUSE_TREECTRL