]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp
wxCheckListBox doesn't require wxUSE_OWNER_DRAWN when using WXUNIVERSAL
[wxWidgets.git] / wxPython / contrib / gizmos / wxCode / src / treelistctrl.cpp
index 288ea108b64175b841ab44b70b3a24389dbe308b..351bb5696036af23915332bfcfc5b3f4fd450f2c 100644 (file)
@@ -39,6 +39,8 @@
 #include <wx/dcclient.h>
 #include <wx/dcscreen.h>
 #include <wx/scrolwin.h>
+#include <wx/renderer.h>
+#include <wx/dcmemory.h>
 
 #include "wx/treelistctrl.h"
 
     #include <wx/gtk/win_gtk.h>
 #endif
 
+#ifdef __WXMAC__
+    #include "wx/mac/private.h"
+#endif
+
+
 // ---------------------------------------------------------------------------
 // array types
 // ---------------------------------------------------------------------------
@@ -80,8 +87,18 @@ const int PIXELS_PER_UNIT = 10;
 const int LINEATROOT = 5;
 const int MARGIN = 2;
 const int MININDENT = 10;
-const int BTNWIDTH = 11;
-const int BTNHEIGHT = 11;
+const int BTNWIDTH = 9; //11;
+const int BTNHEIGHT = 9; //11;
+
+// extra margins around the text label
+static const int EXTRA_WIDTH = 4;
+static const int EXTRA_HEIGHT = 4;
+
+// offset for the header window
+static const int HEADER_OFFSET_X = 1;
+static const int HEADER_OFFSET_Y = 1;
+
+
 
 const wxChar* wxTreeListCtrlNameStr = wxT("treelistctrl");
 
@@ -136,6 +153,7 @@ public:
     void DrawCurrent();
     void AdjustDC(wxDC& dc);
 
+    void OnEraseBackground( wxEraseEvent& event );
     void OnPaint( wxPaintEvent &event );
     void OnMouse( wxMouseEvent &event );
     void OnSetFocus( wxFocusEvent &event );
@@ -549,7 +567,6 @@ public:
     void OnChar( wxKeyEvent &event );
     void OnMouse( wxMouseEvent &event );
     void OnIdle( wxIdleEvent &event );
-    void OnSize(wxSizeEvent& event); // ALB
     void OnScroll(wxScrollWinEvent& event); // ALB
 
     // implementation helpers
@@ -622,6 +639,7 @@ protected:
     wxTreeListItem   *m_dropTarget;
     wxCursor             m_oldCursor;  // cursor is changed while dragging
     wxTreeListItem   *m_oldSelection;
+    wxTreeListItem   *m_underMouse; // for visual effects
 
     wxTimer             *m_renameTimer;
     wxString             m_renameRes;
@@ -1059,9 +1077,10 @@ void wxTreeListTextCtrl::OnKillFocus( wxFocusEvent &event )
 IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow,wxWindow);
 
 BEGIN_EVENT_TABLE(wxTreeListHeaderWindow,wxWindow)
-    EVT_PAINT         (wxTreeListHeaderWindow::OnPaint)
-    EVT_MOUSE_EVENTS  (wxTreeListHeaderWindow::OnMouse)
-    EVT_SET_FOCUS     (wxTreeListHeaderWindow::OnSetFocus)
+    EVT_ERASE_BACKGROUND  (wxTreeListHeaderWindow::OnEraseBackground)
+    EVT_PAINT             (wxTreeListHeaderWindow::OnPaint)
+    EVT_MOUSE_EVENTS      (wxTreeListHeaderWindow::OnMouse)
+    EVT_SET_FOCUS         (wxTreeListHeaderWindow::OnSetFocus)
 END_EVENT_TABLE()
 
 void wxTreeListHeaderWindow::Init()
@@ -1094,7 +1113,7 @@ wxTreeListHeaderWindow::wxTreeListHeaderWindow( wxWindow *win,
     m_owner = owner;
     m_resizeCursor = new wxCursor(wxCURSOR_SIZEWE);
 
-    SetBackgroundColour(wxSystemSettings::GetSystemColour(
+    SetBackgroundColour(wxSystemSettings::GetColour(
                             wxSYS_COLOUR_BTNFACE));
 }
 
@@ -1120,7 +1139,7 @@ void wxTreeListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h )
 
     dc->SetBrush( *wxTRANSPARENT_BRUSH );
 
-    dc->SetPen( wxPen(wxSystemSettings::GetSystemColour(
+    dc->SetPen( wxPen(wxSystemSettings::GetColour(
                           wxSYS_COLOUR_BTNSHADOW), 1, wxSOLID));
     dc->DrawLine( x+w-m_corner+1, y, x+w, y+h );  // right (outer)
     dc->DrawRectangle( x, y+h, w+1, 1 );          // bottom (outer)
@@ -1145,7 +1164,7 @@ void wxTreeListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h )
     dc->DrawLine( x+w-m_corner+1, y, x+w, y+h );  // right (outer)
     dc->DrawRectangle( x, y+h, w+1, 1 );          // bottom (outer)
 
-    wxPen pen(wxSystemSettings::GetSystemColour(
+    wxPen pen(wxSystemSettings::GetColour(
                   wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID);
 
     dc->SetPen( pen );
@@ -1174,34 +1193,42 @@ void wxTreeListHeaderWindow::AdjustDC(wxDC& dc)
     dc.SetDeviceOrigin( -x * xpix, 0 );
 }
 
+
+void wxTreeListHeaderWindow::OnEraseBackground( wxEraseEvent& event )
+{
+}
+
 void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 {
-    static const int HEADER_OFFSET_X = 1, HEADER_OFFSET_Y = 1;
 #ifdef __WXGTK__
-    wxClientDC dc( this );
+    wxClientDC real_dc( this );
 #else
-    wxPaintDC dc( this );
+    wxPaintDC real_dc( this );
 #endif
 
-    PrepareDC( dc );
-    AdjustDC( dc );
-
-    dc.BeginDrawing();
-
-    dc.SetFont( GetFont() );
+    AdjustDC( real_dc );
 
     // width and height of the entire header window
     int w, h;
     GetClientSize( &w, &h );
     m_owner->CalcUnscrolledPosition(w, 0, &w, NULL);
 
+    // Setup double buffering to eliminate the flicker
+    wxMemoryDC dc;
+    wxBitmap   buffer(w, h);
+    dc.SelectObject(buffer);
+    dc.SetBackground(wxBrush(GetBackgroundColour()));
+    dc.Clear();
+    
+    dc.BeginDrawing();
+    dc.SetFont( GetFont() );
     dc.SetBackgroundMode(wxTRANSPARENT);
 
     // do *not* use the listctrl colour for headers - one day we will have a
     // function to set it separately
     //dc.SetTextForeground( *wxBLACK );
     dc.SetTextForeground(wxSystemSettings::
-                            GetSystemColour( wxSYS_COLOUR_WINDOWTEXT ));
+                            GetColour( wxSYS_COLOUR_WINDOWTEXT ));
 
     int x = HEADER_OFFSET_X;
 
@@ -1219,7 +1246,11 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 
         dc.SetPen( *wxWHITE_PEN );
 
-        DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 );
+        //DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 );
+        wxRendererNative::Get().DrawHeaderButton(
+            this, dc, wxRect(x, HEADER_OFFSET_Y, cw, h - 2),
+            m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED);
+        
 
         // if we have an image, draw it on the right of the label
         int image = column.GetImage(); //item.m_image;
@@ -1232,10 +1263,6 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         //else: ignore the column image
         }
 
-        // extra margins around the text label
-        static const int EXTRA_WIDTH = 3;
-        static const int EXTRA_HEIGHT = 4;
-
         int text_width = 0;
         int text_x = x;
         int image_offset = cw - ix - 1;
@@ -1274,14 +1301,19 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         x += wCol;
     }
 
-    int more_w = m_owner->GetSize().x - x;
+    int more_w = m_owner->GetSize().x - x -1;
     if (more_w > 0)
     {
-        DoDrawRect( &dc, x, HEADER_OFFSET_Y, more_w, h-2 );
+        //DoDrawRect( &dc, x, HEADER_OFFSET_Y, more_w, h-2 );
+        wxRendererNative::Get().DrawHeaderButton(
+            this, dc, wxRect(x, HEADER_OFFSET_Y, more_w, h-2),
+            m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED);
     }
 
-
+    // Finish up by drawing the buffer to the real dc
     dc.EndDrawing();
+    dc.SelectObject(wxNullBitmap);
+    real_dc.DrawBitmap(buffer, 0, 0, false);
 }
 
 void wxTreeListHeaderWindow::DrawCurrent()
@@ -1629,7 +1661,7 @@ wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point,
     {
         // evaluate the item
         int h = theCtrl->GetLineHeight(this);
-        if ((point.y > m_y) && (point.y < m_y + h))
+        if ((point.y > m_y) && (point.y <= m_y + h))
         {
             // check for above/below middle
             int y_mid = m_y + h/2;
@@ -1639,19 +1671,29 @@ wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point,
                 flags |= wxTREE_HITTEST_ONITEMLOWERPART;
 
             // check for button hit
-            if (HasPlus() && theCtrl->HasButtons()) {
-                int bntX = m_x - theCtrl->m_btnWidth2;
-                int bntY = y_mid - theCtrl->m_btnHeight2;
-                if ((point.x > bntX) && (point.x < (bntX + theCtrl->m_btnWidth)) &&
-                    (point.y > bntY) && (point.y < (bntY + theCtrl->m_btnHeight))) {
-                    flags |= wxTREE_HITTEST_ONITEMBUTTON;
-                    return this;
-                }
+            int xCross = m_x; // - theCtrl->GetLineSpacing();
+#ifdef __WXMAC__
+            // according to the drawing code the triangels are drawn
+            // at -4 , -4  from the position up to +10/+10 max
+            if ((point.x > xCross-4) && (point.x < xCross+10) &&
+                (point.y > y_mid-4) && (point.y < y_mid+10) &&
+                HasPlus() && theCtrl->HasButtons() )
+#else
+            // 5 is the size of the plus sign
+            if ((point.x > xCross-6) && (point.x < xCross+6) &&
+                (point.y > y_mid-6) && (point.y < y_mid+6) &&
+                HasPlus() && theCtrl->HasButtons() )
+#endif
+            {
+                flags |= wxTREE_HITTEST_ONITEMBUTTON;
+                return this;
             }
 
             // check for image hit
-            if (theCtrl->m_imgWidth > 0) {
+            if (theCtrl->m_imgWidth > 0 && GetImage() != NO_IMAGE) {
                 int imgX = m_x - theCtrl->m_imgWidth2;
+                if (HasPlus() && theCtrl->HasButtons())
+                    imgX += theCtrl->m_btnWidth + LINEATROOT;
                 int imgY = y_mid - theCtrl->m_imgHeight2;
                 if ((point.x >= imgX) && (point.x <= (imgX + theCtrl->m_imgWidth)) &&
                     (point.y >= imgY) && (point.y <= (imgY + theCtrl->m_imgHeight))) {
@@ -1744,6 +1786,7 @@ wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point,
                 column = i;
                 return res;
             }
+            x += w;
         }
     }
 
@@ -1794,7 +1837,6 @@ BEGIN_EVENT_TABLE(wxTreeListMainWindow, wxScrolledWindow)
     EVT_SET_FOCUS      (wxTreeListMainWindow::OnSetFocus)
     EVT_KILL_FOCUS     (wxTreeListMainWindow::OnKillFocus)
     EVT_IDLE           (wxTreeListMainWindow::OnIdle)
-//?    EVT_SIZE           (wxTreeListMainWindow::OnSize)
     EVT_SCROLLWIN      (wxTreeListMainWindow::OnScroll)
 END_EVENT_TABLE()
 
@@ -1812,10 +1854,12 @@ void wxTreeListMainWindow::Init()
     m_lineHeight = LINEHEIGHT;
     m_indent = MININDENT; // min. indent
     m_linespacing = 4;
+    m_imgWidth = 0, m_imgWidth2 = 0;
+    m_imgHeight = 0, m_imgHeight2 = 0;
 
     m_hilightBrush = new wxBrush
                          (
-                            wxSystemSettings::GetSystemColour
+                            wxSystemSettings::GetColour
                             (
                                 wxSYS_COLOUR_HIGHLIGHT
                             ),
@@ -1824,7 +1868,7 @@ void wxTreeListMainWindow::Init()
 
     m_hilightUnfocusedBrush = new wxBrush
                               (
-                                 wxSystemSettings::GetSystemColour
+                                 wxSystemSettings::GetColour
                                  (
                                      wxSYS_COLOUR_BTNSHADOW
                                  ),
@@ -1845,17 +1889,23 @@ void wxTreeListMainWindow::Init()
 
     m_findTimer = new wxTimer (this, -1);
 
-    m_normalFont = wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT );
+    m_underMouse = NULL;
+
+#if defined( __WXMAC__ ) && defined(__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(),
                          wxBOLD,
-                         m_normalFont.GetUnderlined());
+                         m_normalFont.GetUnderlined(),
+                         m_normalFont.GetFaceName(),
+                         m_normalFont.GetEncoding());
 }
 
 
-static const int HEADER_HEIGHT = 23;
-
 bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent,
                                   wxWindowID id,
                                   const wxPoint& pos,
@@ -1865,17 +1915,20 @@ bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent,
                                   const wxString& name )
 {
 #ifdef __WXMAC__
-    int major,minor;
-    wxGetOsVersion( &major, &minor );
-
-    if (style & wxTR_HAS_BUTTONS) style |= wxTR_MAC_BUTTONS;
-    if (style & wxTR_HAS_BUTTONS) style &= ~wxTR_HAS_BUTTONS;
-    style &= ~wxTR_LINES_AT_ROOT;
-    style |= wxTR_NO_LINES;
-    if (major < 10)
-        style |= wxTR_ROW_LINES;
+    if ( !(style & wxTR_DONT_ADJUST_MAC))
+    {
+        int major,minor;
+        wxGetOsVersion( &major, &minor );
+
+        if (style & wxTR_HAS_BUTTONS) style |= wxTR_TWIST_BUTTONS;
+        if (style & wxTR_HAS_BUTTONS) style &= ~wxTR_HAS_BUTTONS;
+        style &= ~wxTR_LINES_AT_ROOT;
+        style |= wxTR_NO_LINES;
+        if (major < 10)
+            style |= wxTR_ROW_LINES;
+    }
 #endif
-
+    
     wxScrolledWindow::Create( parent, id, pos, size,
                               style|wxHSCROLL|wxVSCROLL, name );
 
@@ -1883,7 +1936,7 @@ bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent,
     SetValidator( validator );
 #endif
 
-    SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX ) );
+    SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ) );
 
 #ifdef __WXMSW__
     {
@@ -3250,13 +3303,7 @@ void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc)
         colText = GetForegroundColour();
     }
 
-    wxPen *pen =
-#ifndef __WXMAC__
-        // don't draw rect outline if we already have the
-        // background color under Mac
-        (item->IsSelected() && m_hasFocus) ? wxBLACK_PEN :
-#endif // !__WXMAC__
-         wxTRANSPARENT_PEN;
+    dc.SetPen(*wxTRANSPARENT_PEN);
 
     long text_w = 0, text_h = 0;
 
@@ -3264,22 +3311,24 @@ void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc)
 
     int total_h = GetLineHeight(item);
 
-    if (item->IsSelected() && HasFlag (wxTR_FULL_ROW_HIGHLIGHT)) {
-        dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush));
-        int offset = HasFlag(wxTR_ROW_LINES) ? 1 : 0;
-        dc.DrawRectangle (0, item->GetY() + offset,
-                          m_owner->GetHeaderWindow()->GetWidth(), total_h-offset);
-        colText = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
-    }else{
+    if (item->IsSelected() && HasFlag(wxTR_FULL_ROW_HIGHLIGHT)) {
+            dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush));
+            dc.SetPen(*wxBLACK_PEN);
+            colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
+    } else {
         wxColour colBg;
         if (attr && attr->HasBackgroundColour()) {
             colBg = attr->GetBackgroundColour();
-        }else{
-            colBg = m_backgroundColour;
+        } else {
+            colBg = GetBackgroundColour();
         }
-        dc.SetBrush(wxBrush(colBg, wxTRANSPARENT));
+        dc.SetBrush(wxBrush(colBg, wxSOLID));
     }
 
+    int offset = HasFlag(wxTR_ROW_LINES) ? 1 : 0;
+    dc.DrawRectangle(0, item->GetY() + offset,
+                     m_owner->GetHeaderWindow()->GetWidth(), total_h-offset);
+
     dc.SetBackgroundMode(wxTRANSPARENT);
     int text_extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0;
     int img_extraH = (total_h > m_imgHeight)? (total_h-m_imgHeight)/2: 0;
@@ -3290,9 +3339,9 @@ void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc)
         int image;
         int image_x = 0;
         int image_w = 0;
-        if(i == GetMainColumn()) {
+        if (i == GetMainColumn()) {
             image = item->GetCurrentImage();
-            if (HasButtons()) {
+            if (item->HasPlus()) {
                  image_x = item->GetX() + (m_btnWidth-m_btnWidth2) + LINEATROOT;
             }else{
                  image_x = item->GetX() - m_imgWidth2;
@@ -3323,19 +3372,19 @@ void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc)
         }
         int text_x = image_x + image_w;
 
-        if (item->IsSelected() && (i==GetMainColumn()) && !HasFlag (wxTR_FULL_ROW_HIGHLIGHT))
+        if (item->IsSelected() && (i==GetMainColumn()) && !HasFlag(wxTR_FULL_ROW_HIGHLIGHT))
         {
+            dc.SetPen(*wxBLACK_PEN);
             dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush));
             int offset = HasFlag (wxTR_ROW_LINES) ? 1 : 0;
-            dc.DrawRectangle (text_x, item->GetY() + offset, text_w, total_h-offset);
+            int width = wxMin(text_w+2, colwidth - text_x - x_colstart);
+            dc.DrawRectangle(text_x-1, item->GetY() + offset, width, total_h-offset);
             dc.SetBackgroundMode(wxTRANSPARENT);
-            dc.SetTextForeground(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
+            dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
         }else{
             dc.SetTextForeground(colText);
         }
 
-        dc.SetPen(*pen);
-
         wxDCClipper clipper (dc, x_colstart, item->GetY(), colwidth, total_h);
         if (image != NO_IMAGE)
         {
@@ -3397,6 +3446,9 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc,
 
     if (IsExposed(exposed_x, exposed_y, 10000, h))  // 10000 = very much
     {
+        // draw item
+        PaintItem(item, dc);
+
         if (HasFlag(wxTR_ROW_LINES))
         {
             //dc.DestroyClippingRegion();
@@ -3427,6 +3479,17 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc,
             // clip to the column width
             wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000);
 
+            if ( !HasFlag(wxTR_NO_LINES) )
+            {
+                // draw the horizontal line here
+                int x_start = x;
+                if (x > (signed)m_indent)
+                    x_start -= m_indent;
+                else if (HasFlag(wxTR_LINES_AT_ROOT))
+                    x_start = 3;
+                dc.DrawLine(x_start, y_mid, x /*+ m_spacing*/, y_mid);
+            }
+            
             if (m_imageListButtons != NULL)
             {
                 // draw the image button here
@@ -3441,54 +3504,25 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc,
                                          wxIMAGELIST_DRAW_TRANSPARENT);
                 dc.DestroyClippingRegion();
             }
-            else if (HasFlag(wxTR_TWIST_BUTTONS))
+            else // no custom buttons
             {
-                // draw the twisty button here
-                dc.SetPen(*wxBLACK_PEN);
-                dc.SetBrush(*m_hilightBrush);
-
-                wxPoint button[3];
+                static const int wImage = 9;
+                static const int hImage = 9;
 
+                int flag = 0;
                 if (item->IsExpanded())
-                {
-                    button[0].x = x - (m_btnWidth2+1);
-                    button[0].y = y_mid - (m_btnHeight/3);
-                    button[1].x = x + (m_btnWidth2+1);
-                    button[1].y = button[0].y;
-                    button[2].x = x;
-                    button[2].y = button[0].y + (m_btnHeight2+1);
-                }
-                else
-                {
-                    button[0].x = x - (m_btnWidth/3);
-                    button[0].y = y_mid - (m_btnHeight2+1);
-                    button[1].x = button[0].x;
-                    button[1].y = y_mid + (m_btnHeight2+1);
-                    button[2].x = button[0].x + (m_btnWidth2+1);
-                    button[2].y = y_mid;
-                }
-                dc.DrawPolygon(3, button);
-
-                dc.SetPen(m_dottedPen);
-            }
-            else // if (HasFlag(wxTR_HAS_BUTTONS))
-            {
-                // draw the plus sign here
-                dc.SetPen(*wxGREY_PEN);
-                dc.SetBrush(*wxWHITE_BRUSH);
-                dc.DrawRectangle (x-m_btnWidth2, y_mid-m_btnHeight2,
-                                  m_btnWidth, m_btnHeight);
-                dc.SetPen(*wxBLACK_PEN);
-                dc.DrawLine (x-(m_btnWidth2-3), y_mid,
-                             x+(m_btnWidth2-2), y_mid);
-                if (!item->IsExpanded())
-                    dc.DrawLine (x, y_mid-(m_btnHeight2-2),
-                                 x, y_mid+(m_btnHeight2-1));
-                dc.SetPen(m_dottedPen);
+                    flag |= wxCONTROL_EXPANDED;
+                if (item == m_underMouse)
+                    flag |= wxCONTROL_CURRENT;
+
+                wxRendererNative::Get().DrawTreeItemButton(
+                    this, dc,
+                    wxRect(x - wImage/2, y_mid - hImage/2, wImage, hImage),
+                    flag);
             }
 
             if (!HasFlag(wxTR_NO_LINES)) {
-                if (!(level == 0) && !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) {
+                if (/*!(level == 0) &&*/ !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) {
                     if (m_imgWidth > 0) {
                         dc.DrawLine(x+m_btnWidth2, y_mid, x+m_indent-m_imgWidth2, y_mid);
                     }else{
@@ -3503,19 +3537,15 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc,
             wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000);
 
             // draw the horizontal line here
-            if (!(level == 0) && !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) {
-                int x2 = x;
-                if (!HasButtons()) x2 = x - m_indent;
+            if (/*!(level == 0) &&*/ !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) {
+                int x2 = x - m_indent;
                 if (m_imgWidth > 0) {
                     dc.DrawLine(x2, y_mid, x2+m_indent-m_imgWidth2, y_mid);
                 }else{
-                    dc.DrawLine(x2, y_mid, x2+m_btnWidth2+LINEATROOT-MARGIN, y_mid);
+                    dc.DrawLine(x2, y_mid, x2+m_btnWidth2+LINEATROOT+MARGIN, y_mid);
                 }
             }
         }
-
-        // draw item
-        PaintItem(item, dc);
     }
 
     // restore DC objects
@@ -3526,46 +3556,26 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc,
     if (item->IsExpanded())
     {
         wxArrayTreeListItems& children = item->GetChildren();
+        int count = children.Count();
+        int n, oldY = 0;
 
-        // clip to the column width
-        size_t clip_width = m_owner->GetHeaderWindow()->
-                            GetColumn(m_main_column).GetWidth();
-        wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000);
-
-        // process lower levels
-        int oldY;
-        if (m_imgWidth > 0) {
-            oldY = y_mid + m_imgHeight2;
-        }else{
-            oldY = y_mid + h/2;
+        // paint sublevel items first
+        for (n=0; n<count; ++n) {
+            oldY = y;
+            PaintLevel(children[n], dc, level+1, y, x_colstart);
         }
-        int y2;
-        int n;
-        for (n = 0; n < (int)children.Count(); ++n) {
 
-            if (!HasFlag(wxTR_NO_LINES))
-            {
-                // draw line down to last child
-                if (children[n]->HasPlus() && HasButtons()) {
-                    y2 = y + h/2 - m_btnHeight2;
-                    if (HasButtons()) {
-                        dc.DrawLine(x+m_indent, oldY, x+m_indent, y2);
-                    }else{
-                        dc.DrawLine(x, oldY, x, y2);
-                    }
-                    oldY = y2 + m_btnHeight;
-                }else{
-                    y2 = y + h/2;
-                    if (HasButtons()) {
-                        dc.DrawLine(x+m_indent, oldY, x+m_indent, y2);
-                    }else{
-                        dc.DrawLine(x, oldY, x, y2);
-                    }
-                    oldY = y2;
-                }
-            }
+        // then draw the connecting lines
+        if (!HasFlag(wxTR_NO_LINES) && count > 0)
+        {
+            // clip to the column width
+            size_t clip_width = m_owner->GetHeaderWindow()->GetColumn(m_main_column).GetWidth();
+            wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000);
 
-            PaintLevel (children[n], dc, level+1, y, x_colstart);
+            // draw line down to last child
+            oldY += GetLineHeight(children[n-1]) >> 1;
+            if (HasButtons()) y_mid += 5;
+            dc.DrawLine(x, y_mid, x, oldY);
         }
     }
 }
@@ -4022,12 +4032,8 @@ wxTreeItemId wxTreeListMainWindow::HitTest(const wxPoint& point, int& flags,
         return wxTreeItemId();
     }
 
-    wxClientDC dc(this);
-    PrepareDC(dc);
-    wxCoord x = dc.DeviceToLogicalX( point.x );
-    wxCoord y = dc.DeviceToLogicalY( point.y );
-    wxTreeListItem *hit = m_anchor->HitTest(wxPoint(x, y), this, flags,
-                                            column, 0);
+    wxTreeListItem *hit = m_anchor->HitTest(CalcUnscrolledPosition(point),
+                                            this, flags, column, 0);
     if (hit == NULL)
     {
         flags = wxTREE_HITTEST_NOWHERE;
@@ -4121,6 +4127,60 @@ void wxTreeListMainWindow::OnMouse( wxMouseEvent &event )
 {
     if ( !m_anchor ) return;
 
+    wxPoint pt = CalcUnscrolledPosition(event.GetPosition());
+
+    // Is the mouse over a tree item button?
+    int flags = 0;
+    wxTreeListItem *item = m_anchor->HitTest(pt, this, flags, 0);
+    wxTreeListItem *underMouse = item;
+#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
+            wxTreeListItem *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 = item;
+
+    // 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.SetItem(hoverItem);
+        hevent.SetEventObject(this);
+
+        if ( GetEventHandler()->ProcessEvent(hevent) && hevent.IsAllowed() )
+        {
+            SetToolTip(hevent.GetLabel());
+        }
+    }
+#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
@@ -4138,13 +4198,12 @@ void wxTreeListMainWindow::OnMouse( wxMouseEvent &event )
     if ( event.LeftDown() )
         SetFocus();
 
-    wxClientDC dc(this);
-    PrepareDC(dc);
-    wxCoord x = dc.DeviceToLogicalX( event.GetX() );
-    wxCoord y = dc.DeviceToLogicalY( event.GetY() );
-
-    int flags = 0;
-    wxTreeListItem *item = m_anchor->HitTest(wxPoint(x,y), this, flags, 0);
+//     wxClientDC dc(this);
+//     PrepareDC(dc);
+//     wxCoord x = dc.DeviceToLogicalX( event.GetX() );
+//     wxCoord y = dc.DeviceToLogicalY( event.GetY() );
+    wxCoord &x = pt.x;
+    wxCoord &y = pt.y;
 
     if ( event.Dragging() && !m_isDragging )
     {
@@ -4166,6 +4225,7 @@ void wxTreeListMainWindow::OnMouse( wxMouseEvent &event )
         wxTreeEvent nevent( command,/*ALB*/ m_owner->GetId() );
         nevent.SetItem( (long) m_current);
         nevent.SetEventObject(/*this*/m_owner); // ALB
+        nevent.SetPoint(pt);
 
         // by default the dragging is not supported, the user code must
         // explicitly allow the event for it to take place
@@ -4355,13 +4415,6 @@ void wxTreeListMainWindow::OnIdle( wxIdleEvent &WXUNUSED(event) )
     AdjustMyScrollbars();
 }
 
-void wxTreeListMainWindow::OnSize(wxSizeEvent& WXUNUSED(event))
-{
-//     int w, h;
-//     GetClientSize(&w, &h);
-//     m_header_win->SetSize(0, 0, w, HEADER_HEIGHT);
-}
-
 void wxTreeListMainWindow::OnScroll(wxScrollWinEvent& event)
 {
     // FIXME
@@ -4467,7 +4520,7 @@ void wxTreeListMainWindow::RefreshSubtree(wxTreeListItem *item)
 
     int cw = 0;
     int ch = 0;
-    GetClientSize( &cw, &ch );  // GetVirtualSize???
+    GetVirtualSize( &cw, &ch ); 
 
     wxRect rect;
     rect.x = dc.LogicalToDeviceX( 0 );
@@ -4489,7 +4542,7 @@ void wxTreeListMainWindow::RefreshLine( wxTreeListItem *item )
 
     int cw = 0;
     int ch = 0;
-    GetClientSize( &cw, &ch );   // GetVirtualSize ??
+    GetVirtualSize( &cw, &ch );  
 
     wxRect rect;
     rect.x = dc.LogicalToDeviceX( 0 );
@@ -4580,6 +4633,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxTreeListCtrl, wxControl);
 
 BEGIN_EVENT_TABLE(wxTreeListCtrl, wxControl)
     EVT_SIZE(wxTreeListCtrl::OnSize)
+    EVT_TREE_ITEM_GETTOOLTIP(wxID_ANY, wxTreeListCtrl::OnGetToolTip)
 END_EVENT_TABLE();
 
 bool wxTreeListCtrl::Create(wxWindow *parent, wxWindowID id,
@@ -4601,17 +4655,44 @@ bool wxTreeListCtrl::Create(wxWindow *parent, wxWindowID id,
     m_header_win = new wxTreeListHeaderWindow(this, -1, m_main_win,
                                               wxPoint(0, 0), wxDefaultSize,
                                               wxTAB_TRAVERSAL);
+    CalculateAndSetHeaderHeight();
     return TRUE;
 }
 
-void wxTreeListCtrl::OnSize(wxSizeEvent& WXUNUSED(event))
+void wxTreeListCtrl::CalculateAndSetHeaderHeight()
+{
+    if ( m_header_win )
+    {
+        // we use 'g' to get the descent, too
+        int w, h, d;
+        m_header_win->GetTextExtent(wxT("Hg"), &w, &h, &d);
+        h += d + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT;
+
+        // only update if changed
+        if ( h != (int)m_headerHeight )
+        {
+            m_headerHeight = (size_t)h;
+            m_header_win->SetSize(m_header_win->GetSize().x, m_headerHeight);
+        }
+    }
+}
+
+void wxTreeListCtrl::DoHeaderLayout()
 {
     int w, h;
     GetClientSize(&w, &h);
-    if(m_header_win)
-        m_header_win->SetSize(0, 0, w, HEADER_HEIGHT);
-    if(m_main_win)
-        m_main_win->SetSize(0, HEADER_HEIGHT + 1, w, h - HEADER_HEIGHT - 1);
+    if (m_header_win)
+    {
+        m_header_win->SetSize(0, 0, w, m_headerHeight);
+        m_header_win->Refresh(false);
+    }
+    if (m_main_win)
+        m_main_win->SetSize(0, m_headerHeight + 1, w, h - m_headerHeight - 1);
+}    
+
+void wxTreeListCtrl::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+    DoHeaderLayout();
 }
 
 
@@ -4715,8 +4796,12 @@ void wxTreeListCtrl::SetItemFont(const wxTreeItemId& item,
 
 bool wxTreeListCtrl::SetFont(const wxFont& font)
 {
-    if(m_header_win) m_header_win->SetFont(font);
-    if(m_main_win)
+    if (m_header_win)
+    {
+        m_header_win->SetFont(font);
+        CalculateAndSetHeaderHeight();
+    }
+    if (m_main_win)
         return m_main_win->SetFont(font);
     else return FALSE;
 }
@@ -4896,8 +4981,7 @@ void wxTreeListCtrl::ScrollTo(const wxTreeItemId& item)
 wxTreeItemId wxTreeListCtrl::HitTest(const wxPoint& pos, int& flags,
                                      int& column)
 {
-    return m_main_win->HitTest(m_main_win->ScreenToClient(ClientToScreen(pos)),
-                               flags, column);
+    return m_main_win->HitTest(pos, flags, column);
 }
 
 bool wxTreeListCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect,
@@ -4923,10 +5007,16 @@ wxTreeItemId wxTreeListCtrl::FindItem (const wxTreeItemId& item, const wxString&
 { return m_main_win->FindItem (item, str, flags); }
 
 bool wxTreeListCtrl::SetBackgroundColour(const wxColour& colour)
-{ return m_main_win->SetBackgroundColour(colour); }
+{ 
+    if (!m_main_win) return false;
+    return m_main_win->SetBackgroundColour(colour); 
+}
 
 bool wxTreeListCtrl::SetForegroundColour(const wxColour& colour)
-{ return m_main_win->SetForegroundColour(colour); }
+{ 
+    if (!m_main_win) return false;
+    return m_main_win->SetForegroundColour(colour); 
+}
 
 size_t wxTreeListCtrl::GetColumnCount() const
 { return m_main_win->GetColumnCount(); }
@@ -4953,7 +5043,10 @@ wxString wxTreeListCtrl::GetColumnText(size_t column) const
 { return m_header_win->GetColumnText(column); }
 
 void wxTreeListCtrl::AddColumn(const wxTreeListColumnInfo& col)
-{ m_header_win->AddColumn(col); }
+{
+    m_header_win->AddColumn(col);
+    DoHeaderLayout();
+}
 
 void wxTreeListCtrl::InsertColumn(size_t before,
                                   const wxTreeListColumnInfo& col)
@@ -5013,3 +5106,17 @@ void wxTreeListCtrl::Refresh(bool erase, const wxRect* rect)
 void wxTreeListCtrl::SetFocus()
 { m_main_win->SetFocus(); }
 
+
+wxSize wxTreeListCtrl::DoGetBestSize() const
+{
+    // something is better than nothing...
+    return wxSize(100,80);
+}
+
+// Process the tooltip event, to speed up event processing.
+// Doesn't actually get a tooltip.
+void wxTreeListCtrl::OnGetToolTip( wxTreeEvent &event )
+{
+    event.Veto();
+}
+