]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/treectrl.cpp
no message
[wxWidgets.git] / src / generic / treectrl.cpp
index 57475faf269fdc678d557f58365abd033dfce77d..b4bf89804949141614b103ee0652a4b78563ae90 100644 (file)
@@ -235,13 +235,13 @@ private:
 static void EventFlagsToSelType(long style,
                                 bool shiftDown,
                                 bool ctrlDown,
-                                bool *is_multiple,
-                                bool *extended_select,
-                                bool *unselect_others)
+                                bool &is_multiple,
+                                bool &extended_select,
+                                bool &unselect_others)
 {
-    *is_multiple = (style & wxTR_MULTIPLE) != 0;
-    *extended_select = shiftDown && is_multiple;
-    *unselect_others = !(extended_select || (ctrlDown && is_multiple));
+    is_multiple = (style & wxTR_MULTIPLE) != 0;
+    extended_select = shiftDown && is_multiple;
+    unselect_others = !(extended_select || (ctrlDown && is_multiple));
 }
 
 // -----------------------------------------------------------------------------
@@ -607,7 +607,8 @@ void wxTreeCtrl::Init()
 
     m_dragCount = 0;
     m_isDragging = FALSE;
-    m_dropTarget = (wxGenericTreeItem *)NULL;
+    m_dropTarget =
+    m_oldSelection = (wxGenericTreeItem *)NULL;
 
     m_renameTimer = new wxTreeRenameTimer( this );
 
@@ -1071,13 +1072,36 @@ void wxTreeCtrl::DeleteChildren(const wxTreeItemId& itemId)
 void wxTreeCtrl::Delete(const wxTreeItemId& itemId)
 {
     wxGenericTreeItem *item = itemId.m_pItem;
-    wxGenericTreeItem *parent = item->GetParent();
 
+    // 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 )
+    {
+        if ( itemKey == item )
+        {
+            // m_key_current is a descendant of the item being deleted
+            changeKeyCurrent = TRUE;
+        }
+        else
+        {
+            itemKey = itemKey->GetParent();
+        }
+    }
+
+    wxGenericTreeItem *parent = item->GetParent();
     if ( parent )
     {
         parent->GetChildren().Remove( item );  // remove by value
     }
 
+    if ( changeKeyCurrent )
+    {
+        // may be NULL or not
+        m_key_current = parent;
+    }
+
     item->DeleteChildren(this);
     SendDeleteEvent(item);
     delete item;
@@ -1330,7 +1354,12 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& itemId,
     // shift press
     if (extended_select)
     {
-        if (m_current == NULL) m_current=m_key_current=GetRootItem().m_pItem;
+        if ( !m_current )
+        {
+            m_current =
+            m_key_current = GetRootItem().m_pItem;
+        }
+
         // don't change the mark (m_current)
         SelectItemRange(m_current, item);
     }
@@ -1495,10 +1524,12 @@ void wxTreeCtrl::SetImageList(wxImageList *imageList)
 {
     m_imageListNormal = imageList;
 
+    if ( !m_imageListNormal )
+        return;
+
     // Calculate a m_lineHeight value from the image sizes.
     // May be toggle off. Then wxTreeCtrl will spread when
     // necessary (which might look ugly).
-#if 1
     wxClientDC dc(this);
     m_lineHeight = (int)(dc.GetCharHeight() + 4);
     int width = 0, height = 0,
@@ -1514,7 +1545,6 @@ void wxTreeCtrl::SetImageList(wxImageList *imageList)
         m_lineHeight += 2;                 // at least 2 pixels
     else
         m_lineHeight += m_lineHeight/10;   // otherwise 10% extra spacing
-#endif
 }
 
 void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
@@ -1570,8 +1600,15 @@ void wxTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
     int image = item->GetCurrentImage();
     if ( image != NO_IMAGE )
     {
-        m_imageListNormal->GetSize( image, image_w, image_h );
-        image_w += 4;
+        if ( m_imageListNormal )
+        {
+            m_imageListNormal->GetSize( image, image_w, image_h );
+            image_w += 4;
+        }
+        else
+        {
+            image = NO_IMAGE;
+        }
     }
 
     int total_h = GetLineHeight(item);
@@ -1825,8 +1862,18 @@ void wxTreeCtrl::OnChar( wxKeyEvent &event )
     EventFlagsToSelType(GetWindowStyleFlag(),
                         event.ShiftDown(),
                         event.ControlDown(),
-                        &is_multiple, &extended_select, &unselect_others);
-
+                        is_multiple, extended_select, unselect_others);
+
+    // + : Expand
+    // - : Collaspe
+    // * : Toggle Expand/Collapse
+    // ' ' | return : activate
+    // up    : go up (not last children!)
+    // down  : go down
+    // left  : go to parent
+    // right : open if parent and go next
+    // home  : go to root
+    // end   : go to last item without opening parents
     switch (event.KeyCode())
     {
         case '+':
@@ -1932,7 +1979,6 @@ void wxTreeCtrl::OnChar( wxKeyEvent &event )
                 else
                 {
                     wxTreeItemId next = GetNextSibling( m_key_current );
-//                    if (next == 0)
                     if (!next)
                     {
                         wxTreeItemId current = m_key_current;
@@ -1942,7 +1988,6 @@ void wxTreeCtrl::OnChar( wxKeyEvent &event )
                             if (current) next = GetNextSibling( current );
                         }
                     }
-//                    if (next != 0)
                     if (next)
                     {
                         SelectItem( next, unselect_others, extended_select );
@@ -2051,8 +2096,15 @@ void wxTreeCtrl::Edit( const wxTreeItemId& item )
     int image = m_currentEdit->GetCurrentImage();
     if ( image != NO_IMAGE )
     {
-        m_imageListNormal->GetSize( image, image_w, image_h );
-        image_w += 4;
+        if ( m_imageListNormal )
+        {
+            m_imageListNormal->GetSize( image, image_w, image_h );
+            image_w += 4;
+        }
+        else
+        {
+            wxFAIL_MSG(_T("you must create an image list to use images!"));
+        }
     }
     x += image_w;
     w -= image_w + 4; // I don't know why +4 is needed
@@ -2143,6 +2195,22 @@ void wxTreeCtrl::OnMouse( wxMouseEvent &event )
             // we're going to drag this item
             m_isDragging = TRUE;
 
+            // remember the old cursor because we will change it while
+            // dragging
+            m_oldCursor = m_cursor;
+
+            // in a single selection control, hide the selection temporarily
+            if ( !(GetWindowStyleFlag() & wxTR_MULTIPLE) )
+            {
+                m_oldSelection = GetSelection().m_pItem;
+
+                if ( m_oldSelection )
+                {
+                    m_oldSelection->SetHilight(FALSE);
+                    RefreshLine(m_oldSelection);
+                }
+            }
+
             CaptureMouse();
         }
     }
@@ -2178,9 +2246,16 @@ void wxTreeCtrl::OnMouse( wxMouseEvent &event )
         m_isDragging = FALSE;
         m_dropTarget = (wxGenericTreeItem *)NULL;
 
+        if ( m_oldSelection )
+        {
+            m_oldSelection->SetHilight(TRUE);
+            RefreshLine(m_oldSelection);
+            m_oldSelection = (wxGenericTreeItem *)NULL;
+        }
+
         ReleaseMouse();
 
-        SetCursor(wxCURSOR_DEFAULT);
+        SetCursor(m_oldCursor);
 
         wxYield();
     }
@@ -2213,7 +2288,7 @@ void wxTreeCtrl::OnMouse( wxMouseEvent &event )
             EventFlagsToSelType(GetWindowStyleFlag(),
                                 event.ShiftDown(),
                                 event.ControlDown(),
-                                &is_multiple, &extended_select, &unselect_others);
+                                is_multiple, extended_select, unselect_others);
 
             if ( onButton )
             {
@@ -2253,8 +2328,8 @@ void wxTreeCtrl::OnIdle( wxIdleEvent &WXUNUSED(event) )
 
 void wxTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
 {
-    int text_w = 0;
-    int text_h = 0;
+    wxCoord text_w = 0;
+    wxCoord text_h = 0;
 
     if (item->IsBold())
         dc.SetFont(m_boldFont);
@@ -2270,8 +2345,11 @@ void wxTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
     int image = item->GetCurrentImage();
     if ( image != NO_IMAGE )
     {
-        m_imageListNormal->GetSize( image, image_w, image_h );
-        image_w += 4;
+        if ( m_imageListNormal )
+        {
+            m_imageListNormal->GetSize( image, image_w, image_h );
+            image_w += 4;
+        }
     }
 
     int total_h = (image_h > text_h) ? image_h : text_h;