]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/treectlg.cpp
digital mars updated
[wxWidgets.git] / src / generic / treectlg.cpp
index 46dc5f2919a93104f2f10adc8b8d51ea8e827b4d..f0be2d87232f673442e02b2739abd069a3031cb6 100644 (file)
@@ -5,7 +5,7 @@
 // Created:     01/02/97
 // Modified:    22/10/98 - almost total rewrite, simpler interface (VZ)
 // Id:          $Id$
 // Created:     01/02/97
 // Modified:    22/10/98 - almost total rewrite, simpler interface (VZ)
 // Id:          $Id$
-// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Copyright:   (c) 1998 Robert Roebling and Julian Smart
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #include "wx/settings.h"
 #include "wx/dcclient.h"
 
 #include "wx/settings.h"
 #include "wx/dcclient.h"
 
+#ifdef __WXMAC__
+    #include "wx/mac/private.h"
+#endif
+
 // -----------------------------------------------------------------------------
 // array types
 // -----------------------------------------------------------------------------
 // -----------------------------------------------------------------------------
 // array types
 // -----------------------------------------------------------------------------
@@ -120,6 +124,8 @@ public:
 
 private:
     wxGenericTreeCtrl *m_owner;
 
 private:
     wxGenericTreeCtrl *m_owner;
+
+    DECLARE_NO_COPY_CLASS(wxTreeRenameTimer)
 };
 
 // control used for in-place edit
 };
 
 // control used for in-place edit
@@ -143,6 +149,7 @@ private:
     bool                m_finished;
 
     DECLARE_EVENT_TABLE()
     bool                m_finished;
 
     DECLARE_EVENT_TABLE()
+    DECLARE_NO_COPY_CLASS(wxTreeTextCtrl)
 };
 
 // timer used to clear wxGenericTreeCtrl::m_findPrefix if no key was pressed
 };
 
 // timer used to clear wxGenericTreeCtrl::m_findPrefix if no key was pressed
@@ -159,6 +166,8 @@ public:
 
 private:
     wxGenericTreeCtrl *m_owner;
 
 private:
     wxGenericTreeCtrl *m_owner;
+
+    DECLARE_NO_COPY_CLASS(wxTreeFindTimer)
 };
 
 // a tree item
 };
 
 // a tree item
@@ -287,7 +296,7 @@ private:
     short               m_images[wxTreeItemIcon_Max];
 
     wxCoord             m_x;            // (virtual) offset from top
     short               m_images[wxTreeItemIcon_Max];
 
     wxCoord             m_x;            // (virtual) offset from top
-    short               m_y;            // (virtual) offset from left
+    wxCoord             m_y;            // (virtual) offset from left
     short               m_width;        // width of this item
     unsigned char       m_height;       // height of this item
 
     short               m_width;        // width of this item
     unsigned char       m_height;       // height of this item
 
@@ -298,6 +307,8 @@ private:
                                           // children but has a [+] button
     int                 m_isBold      :1; // render the label in bold font
     int                 m_ownsAttr    :1; // delete attribute when done
                                           // children but has a [+] button
     int                 m_isBold      :1; // render the label in bold font
     int                 m_ownsAttr    :1; // delete attribute when done
+
+    DECLARE_NO_COPY_CLASS(wxGenericTreeItem)
 };
 
 // =============================================================================
 };
 
 // =============================================================================
@@ -723,7 +734,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxGenericTreeCtrl)
 
 void wxGenericTreeCtrl::Init()
 {
 
 void wxGenericTreeCtrl::Init()
 {
-    m_current = m_key_current = m_anchor = (wxGenericTreeItem *) NULL;
+    m_current = m_key_current = m_anchor = m_select_me = (wxGenericTreeItem *) NULL;
     m_hasFocus = FALSE;
     m_dirty = FALSE;
 
     m_hasFocus = FALSE;
     m_dirty = FALSE;
 
@@ -1476,12 +1487,30 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
     // don't keep stale pointers around!
     if ( IsDescendantOf(item, m_key_current) )
     {
     // don't keep stale pointers around!
     if ( IsDescendantOf(item, m_key_current) )
     {
-        m_key_current = parent;
+        // 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;
+    }
+
+    // m_select_me records whether we need to select
+    // a different item, in idle time.
+    if ( m_select_me && IsDescendantOf(item, m_select_me) )
+    {
+        m_select_me = parent;
     }
 
     if ( IsDescendantOf(item, m_current) )
     {
     }
 
     if ( IsDescendantOf(item, m_current) )
     {
-        m_current = parent;
+        // 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;
     }
 
     // remove the item from the tree
     }
 
     // remove the item from the tree
@@ -1623,6 +1652,7 @@ void wxGenericTreeCtrl::Unselect()
         RefreshLine( m_current );
 
         m_current = NULL;
         RefreshLine( m_current );
 
         m_current = NULL;
+        m_select_me = NULL;
     }
 }
 
     }
 }
 
@@ -1708,6 +1738,7 @@ void wxGenericTreeCtrl::SelectItemRange(wxGenericTreeItem *item1, wxGenericTreeI
 {
     // item2 is not necessary after item1
     wxGenericTreeItem *first=NULL, *last=NULL;
 {
     // item2 is not necessary after item1
     wxGenericTreeItem *first=NULL, *last=NULL;
+    m_select_me = NULL;
 
     // choice first' and 'last' between item1 and item2
     if (item1->GetY()<item2->GetY())
 
     // choice first' and 'last' between item1 and item2
     if (item1->GetY()<item2->GetY())
@@ -1735,6 +1766,8 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId,
 {
     wxCHECK_RET( itemId.IsOk(), wxT("invalid tree item") );
 
 {
     wxCHECK_RET( itemId.IsOk(), wxT("invalid tree item") );
 
+    m_select_me = NULL;
+    
     bool is_single=!(GetWindowStyleFlag() & wxTR_MULTIPLE);
     wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
 
     bool is_single=!(GetWindowStyleFlag() & wxTR_MULTIPLE);
     wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
 
@@ -2121,7 +2154,20 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
 
     if ( item->IsSelected() )
     {
 
     if ( item->IsSelected() )
     {
+// under mac selections are only a rectangle in case they don't have the focus
+#ifdef __WXMAC__
+        if ( !m_hasFocus )
+        {
+            dc.SetBrush( *wxTRANSPARENT_BRUSH ) ;
+            dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) , 1 , wxSOLID ) ) ;
+        }
+        else
+        {
+            dc.SetBrush( *m_hilightBrush ) ;
+        }
+#else
         dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush));
         dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush));
+#endif
     }
     else
     {
     }
     else
     {
@@ -2302,10 +2348,26 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
 
                 if (HasFlag(wxTR_AQUA_BUTTONS))
                 {
 
                 if (HasFlag(wxTR_AQUA_BUTTONS))
                 {
+                    // This causes update problems, so disabling for now.
+#if 0 // def __WXMAC__
+                    wxMacPortSetter helper(&dc) ;
+                    wxMacWindowClipper clipper(this) ;
+                    wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
+
+                    int loc_x = x - 5 ;
+                    int loc_y = y_mid - 6 ;
+                    MacWindowToRootWindow( & loc_x , & loc_y ) ;
+                    Rect bounds = { loc_y , loc_x , loc_y + 18 , loc_x + 12 } ;
+                    ThemeButtonDrawInfo info = { kThemeStateActive , item->IsExpanded() ? kThemeDisclosureDown : kThemeDisclosureRight ,
+                        kThemeAdornmentNone }; 
+                    DrawThemeButton( &bounds, kThemeDisclosureButton , 
+                        &info , NULL , NULL , NULL , NULL ) ;
+#else
                     if (item->IsExpanded())
                         dc.DrawBitmap( *m_arrowDown, x-5, y_mid-6, TRUE );
                     else
                         dc.DrawBitmap( *m_arrowRight, x-5, y_mid-6, TRUE );
                     if (item->IsExpanded())
                         dc.DrawBitmap( *m_arrowDown, x-5, y_mid-6, TRUE );
                     else
                         dc.DrawBitmap( *m_arrowRight, x-5, y_mid-6, TRUE );
+#endif
                 }
                 else
                 {
                 }
                 else
                 {
@@ -2378,7 +2440,23 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
                 // draw line down to last child
                 oldY += GetLineHeight(children[n-1])>>1;
                 if (HasButtons()) y_mid += 5;
                 // draw line down to last child
                 oldY += GetLineHeight(children[n-1])>>1;
                 if (HasButtons()) y_mid += 5;
-                dc.DrawLine(x, y_mid, x, oldY);
+
+                // Only draw the portion of the line that is visible, in case it is huge
+                wxCoord        xOrigin=0, yOrigin=0, width, height;
+                dc.GetDeviceOrigin(&xOrigin, &yOrigin);
+                yOrigin = abs(yOrigin);
+                GetClientSize(&width, &height);
+
+                // Move end points to the begining/end of the view?
+                if (y_mid < yOrigin)
+                    y_mid = yOrigin;
+                if (oldY > yOrigin + height)
+                    oldY = yOrigin + height;
+
+                // after the adjustments if y_mid is larger than oldY then the line
+                // isn't visible at all so don't draw anything
+                if (y_mid < oldY)
+                    dc.DrawLine(x, y_mid, x, oldY);
             }
         }
     }
             }
         }
     }
@@ -2522,7 +2600,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
     // home  : go to root
     // end   : go to last item without opening parents
     // alnum : start or continue searching for the item with this prefix
     // home  : go to root
     // end   : go to last item without opening parents
     // alnum : start or continue searching for the item with this prefix
-    int keyCode = event.KeyCode();
+    int keyCode = event.GetKeyCode();
     switch ( keyCode )
     {
         case '+':
     switch ( keyCode )
     {
         case '+':
@@ -3082,6 +3160,18 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
 
 void wxGenericTreeCtrl::OnIdle( wxIdleEvent &WXUNUSED(event) )
 {
 
 void wxGenericTreeCtrl::OnIdle( wxIdleEvent &WXUNUSED(event) )
 {
+    // Check if we need to select the root item
+    // because nothing else has been selected.
+    // Delaying it means that we can invoke event handlers
+    // as required, when a first item is selected.
+    if (!HasFlag(wxTR_MULTIPLE) && !GetSelection().IsOk())
+    {
+        if (m_select_me)
+            SelectItem(m_select_me);
+        else if (GetRootItem().IsOk())
+            SelectItem(GetRootItem());
+    }
+
     /* after all changes have been done to the tree control,
      * we actually redraw the tree when everything is over */
 
     /* after all changes have been done to the tree control,
      * we actually redraw the tree when everything is over */