]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/treectlg.cpp
moved assertdlg_gtk.[ch] to GTK_LOWLEVEL_SRC/HDR to fix wxUniv/GTK build
[wxWidgets.git] / src / generic / treectlg.cpp
index 584ecdc2935fb1a0f468b5439d60c593f526701d..7b29dca54f673b1df91dd7dfcbea5b866e51fae9 100644 (file)
@@ -720,6 +720,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxGenericTreeCtrl, wxControl)
 
 BEGIN_EVENT_TABLE(wxGenericTreeCtrl, wxTreeCtrlBase)
     EVT_PAINT          (wxGenericTreeCtrl::OnPaint)
 
 BEGIN_EVENT_TABLE(wxGenericTreeCtrl, wxTreeCtrlBase)
     EVT_PAINT          (wxGenericTreeCtrl::OnPaint)
+    EVT_SIZE           (wxGenericTreeCtrl::OnSize)
     EVT_MOUSE_EVENTS   (wxGenericTreeCtrl::OnMouse)
     EVT_CHAR           (wxGenericTreeCtrl::OnChar)
     EVT_SET_FOCUS      (wxGenericTreeCtrl::OnSetFocus)
     EVT_MOUSE_EVENTS   (wxGenericTreeCtrl::OnMouse)
     EVT_CHAR           (wxGenericTreeCtrl::OnChar)
     EVT_SET_FOCUS      (wxGenericTreeCtrl::OnSetFocus)
@@ -819,7 +820,14 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent,
     style |= wxTR_NO_LINES;
     if (major < 10)
         style |= wxTR_ROW_LINES;
     style |= wxTR_NO_LINES;
     if (major < 10)
         style |= wxTR_ROW_LINES;
+        
+    if (style == 0 || style & wxTR_DEFAULT_STYLE)
+        style |= wxTR_FULL_ROW_HIGHLIGHT;
+        
 #endif // __WXMAC__
 #endif // __WXMAC__
+#ifdef __WXGTK20__
+    style |= wxTR_NO_LINES;
+#endif
 
     if ( !wxControl::Create( parent, id, pos, size,
                              style|wxHSCROLL|wxVSCROLL,
 
     if ( !wxControl::Create( parent, id, pos, size,
                              style|wxHSCROLL|wxVSCROLL,
@@ -844,7 +852,7 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent,
 
     m_dottedPen = wxPen( wxT("grey"), 0, 0 );
 
 
     m_dottedPen = wxPen( wxT("grey"), 0, 0 );
 
-    SetBestSize(size);
+    SetInitialSize(size);
 
     return true;
 }
 
     return true;
 }
@@ -1021,6 +1029,12 @@ void wxGenericTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold)
     if ( pItem->IsBold() != bold )
     {
         pItem->SetBold(bold);
     if ( pItem->IsBold() != bold )
     {
         pItem->SetBold(bold);
+
+        // recalculate the item size as bold and non bold fonts have different
+        // widths
+        wxClientDC dc(this);
+        CalculateSize(pItem, dc);
+
         RefreshLine(pItem);
     }
 }
         RefreshLine(pItem);
     }
 }
@@ -1389,10 +1403,12 @@ wxTreeItemId wxGenericTreeCtrl::FindItem(const wxTreeItemId& idParent,
         }
 
         // and try all the items (stop when we get to the one we started from)
         }
 
         // and try all the items (stop when we get to the one we started from)
-        while ( id != idParent && !GetItemText(id).Lower().StartsWith(prefix) )
+        while (id.IsOk() && id != idParent && !GetItemText(id).Lower().StartsWith(prefix) )
         {
             id = GetNext(id);
         }
         {
             id = GetNext(id);
         }
+        // If we haven't found the item, id.IsOk() will be false, as per
+        // documentation
     }
 
     return id;
     }
 
     return id;
@@ -1884,9 +1900,16 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, bool select)
     {
         wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
         wxCHECK_RET( item, wxT("SelectItem(): invalid tree item") );
     {
         wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
         wxCHECK_RET( item, wxT("SelectItem(): invalid tree item") );
+        
+        wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGING, this, item);
+        if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() )
+            return;
 
         item->SetHilight(false);
         RefreshLine(item);
 
         item->SetHilight(false);
         RefreshLine(item);
+
+        event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED);
+        GetEventHandler()->ProcessEvent( event );
     }
 }
 
     }
 }
 
@@ -2173,20 +2196,7 @@ 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
         drawItemBackground = true;
     }
     else
         drawItemBackground = true;
     }
     else
@@ -2208,11 +2218,27 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
 
     if ( HasFlag(wxTR_FULL_ROW_HIGHLIGHT) )
     {
 
     if ( HasFlag(wxTR_FULL_ROW_HIGHLIGHT) )
     {
-        int x, y, w, h;
-
-        DoGetPosition(&x, &y);
-        DoGetSize(&w, &h);
-        dc.DrawRectangle(x, item->GetY()+offset, w, total_h-offset);
+        int x, w, h;
+        x=0;
+        GetVirtualSize(&w, &h);
+        wxRect rect( x, item->GetY()+offset, w, total_h-offset);
+#if !defined(__WXGTK20__) && !defined(__WXMAC__)
+        dc.DrawRectangle(rect);
+#else
+        if (!item->IsSelected())
+        {
+            dc.DrawRectangle(rect);
+        }
+        else
+        {
+            int flags = wxCONTROL_SELECTED;
+            if (m_hasFocus)
+                flags |= wxCONTROL_FOCUSED;
+            if ((item == m_current) && (m_hasFocus))
+                flags |= wxCONTROL_CURRENT;
+            wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, flags );
+        }
+#endif
     }
     else
     {
     }
     else
     {
@@ -2221,16 +2247,49 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
             // If it's selected, and there's an image, then we should
             // take care to leave the area under the image painted in the
             // background colour.
             // If it's selected, and there's an image, then we should
             // take care to leave the area under the image painted in the
             // background colour.
-            dc.DrawRectangle( item->GetX() + image_w - 2, item->GetY()+offset,
-                              item->GetWidth() - image_w + 2, total_h-offset );
+            wxRect rect( item->GetX() + image_w - 2, item->GetY()+offset,
+                         item->GetWidth() - image_w + 2, total_h-offset );
+#if !defined(__WXGTK20__) && !defined(__WXMAC__)
+            dc.DrawRectangle( rect );
+#else
+            rect.x -= 1;
+            rect.width += 2;
+        
+            int flags = wxCONTROL_SELECTED;
+            if (m_hasFocus)
+                flags |= wxCONTROL_FOCUSED;
+            if ((item == m_current) && (m_hasFocus))
+                flags |= wxCONTROL_CURRENT;
+            wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, flags );
+#endif
         }
         // On GTK+ 2, drawing a 'normal' background is wrong for themes that
         // don't allow backgrounds to be customized. Not drawing the background,
         // except for custom item backgrounds, works for both kinds of theme.
         else if (drawItemBackground)
         {
         }
         // On GTK+ 2, drawing a 'normal' background is wrong for themes that
         // don't allow backgrounds to be customized. Not drawing the background,
         // except for custom item backgrounds, works for both kinds of theme.
         else if (drawItemBackground)
         {
-            dc.DrawRectangle( item->GetX()-2, item->GetY()+offset,
-                              item->GetWidth()+2, total_h-offset );
+            wxRect rect( item->GetX()-2, item->GetY()+offset,
+                         item->GetWidth()+2, total_h-offset );
+#if !defined(__WXGTK20__) && !defined(__WXMAC__)
+            dc.DrawRectangle( rect );
+#else
+            if ( attr && attr->HasBackgroundColour() )
+            {
+                dc.DrawRectangle( rect );
+            }
+            else
+            {
+                rect.x -= 1;
+                rect.width += 2;
+                
+                int flags = wxCONTROL_SELECTED;
+                if (m_hasFocus)
+                    flags |= wxCONTROL_FOCUSED;
+                if ((item == m_current) && (m_hasFocus))
+                    flags |= wxCONTROL_CURRENT;
+                wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, flags );
+            }
+#endif
         }
     }
 
         }
     }
 
@@ -2319,7 +2378,11 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
 #endif
             )
         {
 #endif
             )
         {
+#ifdef __WXMAC__
+            colText = *wxWHITE;
+#else
             colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
             colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
+#endif
         }
         else
         {
         }
         else
         {
@@ -2514,6 +2577,16 @@ void wxGenericTreeCtrl::DrawLine(const wxTreeItemId &item, bool below)
 // wxWidgets callbacks
 // -----------------------------------------------------------------------------
 
 // wxWidgets callbacks
 // -----------------------------------------------------------------------------
 
+void wxGenericTreeCtrl::OnSize( wxSizeEvent &event )
+{
+#ifdef __WXGTK__
+    if (HasFlag( wxTR_FULL_ROW_HIGHLIGHT) && m_current)
+        RefreshLine( m_current );
+#endif
+
+    event.Skip(true);
+}
+
 void wxGenericTreeCtrl::OnPaint( wxPaintEvent &WXUNUSED(event) )
 {
     wxPaintDC dc(this);
 void wxGenericTreeCtrl::OnPaint( wxPaintEvent &WXUNUSED(event) )
 {
     wxPaintDC dc(this);
@@ -2574,6 +2647,14 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
                         event.CmdDown(),
                         is_multiple, extended_select, unselect_others);
 
                         event.CmdDown(),
                         is_multiple, extended_select, unselect_others);
 
+    if (GetLayoutDirection() == wxLayout_RightToLeft)
+    {
+        if (event.GetKeyCode() == WXK_RIGHT)
+            event.m_keyCode = WXK_LEFT;
+        else if (event.GetKeyCode() == WXK_LEFT)
+            event.m_keyCode = WXK_RIGHT;
+    }
+
     // + : Expand
     // - : Collaspe
     // * : Expand all/Collapse all
     // + : Expand
     // - : Collaspe
     // * : Expand all/Collapse all
@@ -3016,11 +3097,12 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
     }
 #endif
 
     }
 #endif
 
-    // we process left mouse up event (enables in-place edit), right down
+    // we process left mouse up event (enables in-place edit), middle/right down
     // (pass to the user code), left dbl click (activate item) and
     // dragging/moving events for items drag-and-drop
     if ( !(event.LeftDown() ||
            event.LeftUp() ||
     // (pass to the user code), left dbl click (activate item) and
     // dragging/moving events for items drag-and-drop
     if ( !(event.LeftDown() ||
            event.LeftUp() ||
+           event.MiddleDown() ||
            event.RightDown() ||
            event.LeftDClick() ||
            event.Dragging() ||
            event.RightDown() ||
            event.LeftDClick() ||
            event.Dragging() ||
@@ -3171,6 +3253,12 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
             nevent2.m_pointDrag = CalcScrolledPosition(pt);
             GetEventHandler()->ProcessEvent(nevent2);
         }
             nevent2.m_pointDrag = CalcScrolledPosition(pt);
             GetEventHandler()->ProcessEvent(nevent2);
         }
+        else if ( event.MiddleDown() )
+        {
+            wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK,  this, item);
+            nevent.m_pointDrag = CalcScrolledPosition(pt);
+            event.Skip(!GetEventHandler()->ProcessEvent(nevent));
+        }
         else if ( event.LeftUp() )
         {
             // this facilitates multiple-item drag-and-drop
         else if ( event.LeftUp() )
         {
             // this facilitates multiple-item drag-and-drop
@@ -3210,7 +3298,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
                 m_lastOnSame = false;
             }
         }
                 m_lastOnSame = false;
             }
         }
-        else // !RightDown() && !LeftUp() ==> LeftDown() || LeftDClick()
+        else // !RightDown() && !MiddleDown() && !LeftUp() ==> LeftDown() || LeftDClick()
         {
             if ( event.LeftDown() )
             {
         {
             if ( event.LeftDown() )
             {
@@ -3559,4 +3647,35 @@ void wxGenericTreeCtrl::DoDirtyProcessing()
     AdjustMyScrollbars();
 }
 
     AdjustMyScrollbars();
 }
 
+wxSize wxGenericTreeCtrl::DoGetBestSize() const
+{
+    // make sure all positions are calculated as normally this only done during
+    // idle time but we need them for base class DoGetBestSize() to return the
+    // correct result
+    wxConstCast(this, wxGenericTreeCtrl)->CalculatePositions();
+
+    wxSize size = wxTreeCtrlBase::DoGetBestSize();
+
+    // there seems to be an implicit extra border around the items, although
+    // I'm not really sure where does it come from -- but without this, the
+    // scrollbars appear in a tree with default/best size
+    size.IncBy(4, 4);
+
+    // and the border has to be rounded up to a multiple of PIXELS_PER_UNIT or
+    // scrollbars still appear
+    const wxSize& borderSize = GetWindowBorderSize();
+
+    int dx = (size.x - borderSize.x) % PIXELS_PER_UNIT;
+    if ( dx )
+        size.x += PIXELS_PER_UNIT - dx;
+    int dy = (size.y - borderSize.y) % PIXELS_PER_UNIT;
+    if ( dy )
+        size.y += PIXELS_PER_UNIT - dy;
+
+    // we need to update the cache too as the base class cached its own value
+    CacheBestSize(size);
+
+    return size;
+}
+
 #endif // wxUSE_TREECTRL
 #endif // wxUSE_TREECTRL