]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/treectrl.cpp
pointer returned by GetNativeFontInfo() is now const and must not be deleted (replace...
[wxWidgets.git] / src / msw / treectrl.cpp
index 342d8188d7eb9aa209a1b28af428ca06b3edb884..baaccbd974ce9e73f2664c9dca87469756690672 100644 (file)
@@ -17,7 +17,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "treectrl.h"
 #endif
 
 #include "wx/msw/treectrl.h"
 #include "wx/msw/dragimag.h"
 
-#ifdef __GNUWIN32_OLD__
-    #include "wx/msw/gnuwin32/extra.h"
-#endif
-
-#if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__))
-    #include <commctrl.h>
-#endif
+// include <commctrl.h> "properly"
+#include "wx/msw/wrapcctl.h"
 
-// Bug in headers, sometimes
-#ifndef TVIS_FOCUSED
-    #define TVIS_FOCUSED            0x0001
-#endif
-
-#ifndef TV_FIRST
-    #define TV_FIRST                0x1100
-#endif
+// macros to hide the cast ugliness
+// --------------------------------
 
-#ifndef TVS_CHECKBOXES
-    #define TVS_CHECKBOXES          0x0100
-#endif
-
-#ifndef TVS_FULLROWSELECT
-    #define TVS_FULLROWSELECT       0x1000
-#endif
-
-// old headers might miss these messages (comctl32.dll 4.71+ only)
-#ifndef TVM_SETBKCOLOR
-    #define TVM_SETBKCOLOR          (TV_FIRST + 29)
-    #define TVM_SETTEXTCOLOR        (TV_FIRST + 30)
-#endif
+// ptr is the real item id, i.e. wxTreeItemId::m_pItem
+#define HITEM_PTR(ptr)     (HTREEITEM)(ptr)
 
-// a macro to hide the cast ugliness
-#define HITEM(item)     (HTREEITEM)((item).m_pItem)
+// item here is a wxTreeItemId
+#define HITEM(item)     HITEM_PTR((item).m_pItem)
 
 // the native control doesn't support multiple selections under MSW and we
 // have 2 ways to emulate them: either using TVS_CHECKBOXES style and let
@@ -392,6 +370,8 @@ public:
 
 private:
     wxArrayTreeItemIds& m_selections;
+
+    DECLARE_NO_COPY_CLASS(TraverseSelections)
 };
 
 // internal class for counting tree items
@@ -419,6 +399,8 @@ public:
 
 private:
     size_t m_count;
+
+    DECLARE_NO_COPY_CLASS(TraverseCounter)
 };
 
 // ----------------------------------------------------------------------------
@@ -488,7 +470,69 @@ private:
 // wxWin macros
 // ----------------------------------------------------------------------------
 
+#if wxUSE_EXTENDED_RTTI
+WX_DEFINE_FLAGS( wxTreeCtrlStyle )
+
+wxBEGIN_FLAGS( wxTreeCtrlStyle )
+    // new style border flags, we put them first to
+    // use them for streaming out
+    wxFLAGS_MEMBER(wxBORDER_SIMPLE)
+    wxFLAGS_MEMBER(wxBORDER_SUNKEN)
+    wxFLAGS_MEMBER(wxBORDER_DOUBLE)
+    wxFLAGS_MEMBER(wxBORDER_RAISED)
+    wxFLAGS_MEMBER(wxBORDER_STATIC)
+    wxFLAGS_MEMBER(wxBORDER_NONE)
+    
+    // old style border flags
+    wxFLAGS_MEMBER(wxSIMPLE_BORDER)
+    wxFLAGS_MEMBER(wxSUNKEN_BORDER)
+    wxFLAGS_MEMBER(wxDOUBLE_BORDER)
+    wxFLAGS_MEMBER(wxRAISED_BORDER)
+    wxFLAGS_MEMBER(wxSTATIC_BORDER)
+    wxFLAGS_MEMBER(wxBORDER)
+
+    // standard window styles
+    wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
+    wxFLAGS_MEMBER(wxCLIP_CHILDREN)
+    wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
+    wxFLAGS_MEMBER(wxWANTS_CHARS)
+    wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
+    wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
+    wxFLAGS_MEMBER(wxVSCROLL)
+    wxFLAGS_MEMBER(wxHSCROLL)
+
+    wxFLAGS_MEMBER(wxTR_EDIT_LABELS)
+    wxFLAGS_MEMBER(wxTR_NO_BUTTONS)
+    wxFLAGS_MEMBER(wxTR_HAS_BUTTONS)
+    wxFLAGS_MEMBER(wxTR_TWIST_BUTTONS)
+    wxFLAGS_MEMBER(wxTR_NO_LINES)
+    wxFLAGS_MEMBER(wxTR_FULL_ROW_HIGHLIGHT)
+    wxFLAGS_MEMBER(wxTR_LINES_AT_ROOT)
+    wxFLAGS_MEMBER(wxTR_HIDE_ROOT)
+    wxFLAGS_MEMBER(wxTR_ROW_LINES)
+    wxFLAGS_MEMBER(wxTR_HAS_VARIABLE_ROW_HEIGHT)
+    wxFLAGS_MEMBER(wxTR_SINGLE)
+    wxFLAGS_MEMBER(wxTR_MULTIPLE)
+    wxFLAGS_MEMBER(wxTR_EXTENDED)
+    wxFLAGS_MEMBER(wxTR_DEFAULT_STYLE)
+
+wxEND_FLAGS( wxTreeCtrlStyle )
+
+IMPLEMENT_DYNAMIC_CLASS_XTI(wxTreeCtrl, wxControl,"wx/treectrl.h")
+
+wxBEGIN_PROPERTIES_TABLE(wxTreeCtrl)
+    wxEVENT_PROPERTY( TextUpdated , wxEVT_COMMAND_TEXT_UPDATED , wxCommandEvent ) 
+    wxEVENT_RANGE_PROPERTY( TreeEvent , wxEVT_COMMAND_TREE_BEGIN_DRAG , wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK , wxTreeEvent )
+    wxPROPERTY_FLAGS( WindowStyle , wxTreeCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
+wxEND_PROPERTIES_TABLE()
+
+wxBEGIN_HANDLERS_TABLE(wxTreeCtrl)
+wxEND_HANDLERS_TABLE()
+
+wxCONSTRUCTOR_5( wxTreeCtrl , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle ) 
+#else
 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
+#endif
 
 // ----------------------------------------------------------------------------
 // constants
@@ -569,7 +613,6 @@ void wxTreeCtrl::Init()
     m_textCtrl = NULL;
     m_hasAnyAttr = false;
     m_dragImage = NULL;
-    m_htSelStart = 0;
     m_pVirtualRoot = NULL;
 
     // initialize the global array of events now as it can't be done statically
@@ -1010,7 +1053,8 @@ void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
         case wxTreeItemIcon_Normal:
             {
                 const int imageNormalOld = GetItemImage(item);
-                const int imageSelOld = GetItemSelectedImage(item);
+                const int imageSelOld =
+                    GetItemImage(item, wxTreeItemIcon_Selected);
 
                 // always set the normal image
                 imageNormal = image;
@@ -1035,7 +1079,7 @@ void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
                 // the wxTreeItemIndirectData GetItemXXXImage() will use it to
                 // get the images
                 imageNormal = GetItemImage(item);
-                imageSel = GetItemSelectedImage(item);
+                imageSel = GetItemImage(item, wxTreeItemIcon_Selected);
 
                 // if it doesn't have it yet, add it
                 wxTreeItemIndirectData *data = new
@@ -1189,21 +1233,21 @@ void wxTreeCtrl::RefreshItem(const wxTreeItemId& item)
 
 wxColour wxTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const
 {
-    wxMapTreeAttr::const_iterator it = m_attrs.find(item);
+    wxMapTreeAttr::const_iterator it = m_attrs.find(item.m_pItem);
 
     return it == m_attrs.end() ? wxNullColour : it->second->GetTextColour();
 }
 
 wxColour wxTreeCtrl::GetItemBackgroundColour(const wxTreeItemId& item) const
 {
-    wxMapTreeAttr::const_iterator it = m_attrs.find(item);
+    wxMapTreeAttr::const_iterator it = m_attrs.find(item.m_pItem);
 
     return it == m_attrs.end() ? wxNullColour : it->second->GetBackgroundColour();
 }
 
 wxFont wxTreeCtrl::GetItemFont(const wxTreeItemId& item) const
 {
-    wxMapTreeAttr::const_iterator it = m_attrs.find(item);
+    wxMapTreeAttr::const_iterator it = m_attrs.find(item.m_pItem);
 
     return it == m_attrs.end() ? wxNullFont : it->second->GetFont();
 }
@@ -1212,12 +1256,12 @@ void wxTreeCtrl::SetItemTextColour(const wxTreeItemId& item,
                                    const wxColour& col)
 {
     wxTreeItemAttr *attr;
-    wxMapTreeAttr::iterator it = m_attrs.find(item);
+    wxMapTreeAttr::iterator it = m_attrs.find(item.m_pItem);
     if ( it == m_attrs.end() )
     {
         m_hasAnyAttr = true;
 
-        m_attrs[item] =
+        m_attrs[item.m_pItem] =
         attr = new wxTreeItemAttr;
     }
     else
@@ -1234,12 +1278,12 @@ void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId& item,
                                          const wxColour& col)
 {
     wxTreeItemAttr *attr;
-    wxMapTreeAttr::iterator it = m_attrs.find(item);
+    wxMapTreeAttr::iterator it = m_attrs.find(item.m_pItem);
     if ( it == m_attrs.end() )
     {
         m_hasAnyAttr = true;
 
-        m_attrs[item] =
+        m_attrs[item.m_pItem] =
         attr = new wxTreeItemAttr;
     }
     else // already in the hash
@@ -1255,12 +1299,12 @@ void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId& item,
 void wxTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font)
 {
     wxTreeItemAttr *attr;
-    wxMapTreeAttr::iterator it = m_attrs.find(item);
+    wxMapTreeAttr::iterator it = m_attrs.find(item.m_pItem);
     if ( it == m_attrs.end() )
     {
         m_hasAnyAttr = true;
 
-        m_attrs[item] =
+        m_attrs[item.m_pItem] =
         attr = new wxTreeItemAttr;
     }
     else // already in the hash
@@ -1292,8 +1336,18 @@ bool wxTreeCtrl::IsVisible(const wxTreeItemId& item) const
     // the HTREEITEM with TVM_GETITEMRECT
     *(HTREEITEM *)&rect = HITEM(item);
 
-    // false means get item rect for the whole item, not only text
-    return SendMessage(GetHwnd(), TVM_GETITEMRECT, false, (LPARAM)&rect) != 0;
+    // true means to get rect for just the text, not the whole line
+    if ( !::SendMessage(GetHwnd(), TVM_GETITEMRECT, true, (LPARAM)&rect) )
+    {
+        // if TVM_GETITEMRECT returned false, then the item is definitely not
+        // visible (because its parent is not expanded)
+        return false;
+    }
+
+    // however if it returned true, the item might still be outside the
+    // currently visible part of the tree, test for it (notice that partly
+    // visible means visible here)
+    return rect.bottom > 0 && rect.top < GetClientSize().y;
 }
 
 bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const
@@ -1346,7 +1400,7 @@ wxTreeItemId wxTreeCtrl::GetRootItem() const
 
 wxTreeItemId wxTreeCtrl::GetSelection() const
 {
-    wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), NULL,
+    wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), wxTreeItemId(),
                  wxT("this only works with single selection controls") );
 
     return wxTreeItemId(TreeView_GetSelection(GetHwnd()));
@@ -1602,7 +1656,7 @@ wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text,
         return TVI_ROOT;
     }
 
-    return DoInsertItem(wxTreeItemId(), 0,
+    return DoInsertItem(wxTreeItemId(), wxTreeItemId(),
                         text, image, selectedImage, data);
 }
 
@@ -1682,7 +1736,7 @@ void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item)
     size_t nCount = children.Count();
     for ( size_t n = 0; n < nCount; n++ )
     {
-        if ( !TreeView_DeleteItem(GetHwnd(), HITEM(children[n])) )
+        if ( !TreeView_DeleteItem(GetHwnd(), HITEM_PTR(children[n])) )
         {
             wxLogLastError(wxT("TreeView_DeleteItem"));
         }
@@ -1767,10 +1821,12 @@ void wxTreeCtrl::Toggle(const wxTreeItemId& item)
     DoExpand(item, TVE_TOGGLE);
 }
 
+#if WXWIN_COMPATIBILITY_2_4
 void wxTreeCtrl::ExpandItem(const wxTreeItemId& item, int action)
 {
     DoExpand(item, action);
 }
+#endif
 
 void wxTreeCtrl::Unselect()
 {
@@ -1790,9 +1846,9 @@ void wxTreeCtrl::UnselectAll()
         for ( size_t n = 0; n < count; n++ )
         {
 #if wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
-            SetItemCheck(selections[n], false);
+            SetItemCheck(HITEM_PTR(selections[n]), false);
 #else // !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
-            ::UnselectItem(GetHwnd(), HITEM(selections[n]));
+            ::UnselectItem(GetHwnd(), HITEM_PTR(selections[n]));
 #endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE/!wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE
         }
     }
@@ -2106,7 +2162,7 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
                         ::SetFocus(GetHwnd(), htItem);
 
                         // reset on any click without Shift
-                        m_htSelStart = 0;
+                        m_htSelStart.Unset();
 
                         processed = true;
                     }
@@ -2137,7 +2193,7 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
                         size_t count = GetSelections(selections);
                         if ( count == 0 ||
                              count > 1 ||
-                             HITEM(selections[0]) != htItem )
+                             HITEM_PTR(selections[0]) != htItem )
                         {
                             // clear the previously selected items, if the
                             // user clicked outside of the present selection.
@@ -2163,7 +2219,7 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
                         }
 
                         // reset on any click without Shift
-                        m_htSelStart = 0;
+                        m_htSelStart.Unset();
                     }
                 }
                 break;
@@ -2239,7 +2295,7 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
         {
             // TreeView_GetItemRect() will return false if item is not visible,
             // which may happen perfectly well
-            if ( TreeView_GetItemRect(GetHwnd(), HITEM(selections[n]),
+            if ( TreeView_GetItemRect(GetHwnd(), HITEM_PTR(selections[n]),
                                       &rect, true) )
             {
                 ::InvalidateRect(GetHwnd(), &rect, false);
@@ -2531,7 +2587,9 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
             }
             break;
 
-#if defined(_WIN32_IE) && _WIN32_IE >= 0x300 && !wxUSE_COMCTL32_SAFELY && !( defined(__GNUWIN32__) && !wxCHECK_W32API_VERSION( 1, 0 ) )
+            // instead of explicitly checking for _WIN32_IE, check if the
+            // required symbols are available in the headers
+#if defined(CDDS_PREPAINT) && !wxUSE_COMCTL32_SAFELY
         case NM_CUSTOMDRAW:
             {
                 LPNMTVCUSTOMDRAW lptvcd = (LPNMTVCUSTOMDRAW)lParam;
@@ -2626,7 +2684,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 
             // we always process it
             return true;
-#endif // _WIN32_IE >= 0x300
+#endif // have owner drawn support in headers
 
         case NM_CLICK:
             {