X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a32dd69091fec647103402959b39b2fd8118a27f..c6cdf16c933251be1670f611ba28e48885610b23:/src/generic/treectrl.cpp?ds=sidebyside diff --git a/src/generic/treectrl.cpp b/src/generic/treectrl.cpp index bbb5b9ade5..c9c35cb94d 100644 --- a/src/generic/treectrl.cpp +++ b/src/generic/treectrl.cpp @@ -3,7 +3,7 @@ // Purpose: // Author: Robert Roebling // Created: 01/02/97 -// Id: +// Id: $Id$ // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -14,6 +14,7 @@ #include "wx/treectrl.h" #include "wx/settings.h" +#include "wx/log.h" //----------------------------------------------------------------------------- // wxTreeItem @@ -210,7 +211,7 @@ void wxGenericTreeItem::GetSize( int &x, int &y ) long wxGenericTreeItem::HitTest( const wxPoint& point, int &flags ) { - if (m_parent && ((point.y > m_y) && (point.y < m_y+m_height))) + if ((point.y > m_y) && (point.y < m_y+m_height)) { if ((point.x > m_xCross-5) && (point.x < m_xCross+5) && @@ -236,13 +237,16 @@ long wxGenericTreeItem::HitTest( const wxPoint& point, int &flags ) } else { - wxNode *node = m_children.First(); - while (node) + if (!m_isCollapsed) { - wxGenericTreeItem *child = (wxGenericTreeItem*)node->Data(); - long res = child->HitTest( point, flags ); - if (res != -1) return res; - node = node->Next(); + wxNode *node = m_children.First(); + while (node) + { + wxGenericTreeItem *child = (wxGenericTreeItem*)node->Data(); + long res = child->HitTest( point, flags ); + if (res != -1) return res; + node = node->Next(); + }; }; }; return -1; @@ -292,7 +296,6 @@ void wxGenericTreeItem::SendExpand( wxWindow *target ) m_isCollapsed = FALSE; wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, target->GetId() ); - event.SetCode(wxTREE_EXPAND_EXPAND); event.SetEventObject( target ); PrepareEvent( event ); target->ProcessEvent( event ); @@ -306,13 +309,12 @@ void wxGenericTreeItem::SendCollapse( wxWindow *target ) { m_isCollapsed = TRUE; - wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, target->GetId() ); - event.SetCode(wxTREE_EXPAND_COLLAPSE); + wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING, target->GetId() ); event.SetEventObject( target ); PrepareEvent( event ); target->ProcessEvent( event ); - event.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED); + event.SetEventType(wxEVT_COMMAND_TREE_ITEM_COLLAPSED); PrepareEvent( event ); target->ProcessEvent( event ); }; @@ -331,8 +333,7 @@ bool wxGenericTreeItem::HasHilight() // wxTreeCtrl //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl,wxScrolledWindow -) +IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl,wxScrolledWindow) BEGIN_EVENT_TABLE(wxTreeCtrl,wxScrolledWindow) EVT_PAINT (wxTreeCtrl::OnPaint) @@ -353,13 +354,13 @@ wxTreeCtrl::wxTreeCtrl() m_lineHeight = 10; m_indent = 15; m_isCreated = FALSE; - m_dc = NULL; m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID ); + m_imageList = NULL; + m_smallImageList = NULL; }; wxTreeCtrl::wxTreeCtrl(wxWindow *parent, wxWindowID id, - const wxPoint& pos, - const wxSize& size, + const wxPoint& pos, const wxSize& size, long style, const wxString& name ) { m_current = NULL; @@ -371,21 +372,19 @@ wxTreeCtrl::wxTreeCtrl(wxWindow *parent, wxWindowID id, m_lineHeight = 10; m_indent = 15; m_isCreated = FALSE; - m_dc = NULL; m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID ); + m_imageList = NULL; + m_smallImageList = NULL; Create( parent, id, pos, size, style, name ); }; wxTreeCtrl::~wxTreeCtrl() { - if (m_dc) delete m_dc; }; bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style -, const wxString& name ) + const wxPoint& pos, const wxSize& size, + long style, const wxString& name ) { wxScrolledWindow::Create( parent, id, pos, size, style, name ); SetBackgroundColour( *wxWHITE ); @@ -443,14 +442,19 @@ long wxTreeCtrl::InsertItem( long parent, const wxString& label, int image, { CalculatePositions(); + if (!p->HasChildren()) p->m_hasChildren = TRUE; + int ch = 0; GetClientSize( NULL, &ch ); + PrepareDC( dc ); + wxRectangle rect; - rect.x = 0; rect.y = 0; - rect.width = 10000; rect.height = ch; + rect.x = dc.LogicalToDeviceX( 0 ); + rect.y = 0; + rect.width = 10000; + rect.height = ch; - PrepareDC( dc ); if (p->m_children.Number() == 1) { rect.y = dc.LogicalToDeviceY( p->m_y ); @@ -462,11 +466,6 @@ long wxTreeCtrl::InsertItem( long parent, const wxString& label, int image, rect.y = dc.LogicalToDeviceY( last_child->m_y ); }; - long doX = 0; - long doY = 0; - dc.GetDeviceOrigin( &doX, &doY ); - rect.height = ch-rect.y-doY; - AdjustMyScrollbars(); if (rect.height > 0) Refresh( FALSE, &rect); @@ -522,14 +521,19 @@ long wxTreeCtrl::InsertItem( long parent, wxTreeItem &info, long WXUNUSED(insert { CalculatePositions(); + if (!p->HasChildren()) p->m_hasChildren = TRUE; + int ch = 0; GetClientSize( NULL, &ch ); + PrepareDC( dc ); + wxRectangle rect; - rect.x = 0; rect.y = 0; - rect.width = 10000; rect.height = ch; + rect.x = dc.LogicalToDeviceX( 0 ); + rect.y = 0; + rect.width = 10000; + rect.height = ch; - PrepareDC( dc ); if (p->m_children.Number() == 1) { rect.y = dc.LogicalToDeviceY( p->m_y ); @@ -541,11 +545,6 @@ long wxTreeCtrl::InsertItem( long parent, wxTreeItem &info, long WXUNUSED(insert rect.y = dc.LogicalToDeviceY( last_child->m_y ); }; - long doX = 0; - long doY = 0; - dc.GetDeviceOrigin( &doX, &doY ); - rect.height = ch-rect.y-doY; - AdjustMyScrollbars(); if (rect.height > 0) Refresh( FALSE, &rect); @@ -582,17 +581,13 @@ bool wxTreeCtrl::ExpandItem( long item, int action ) while (node) { wxGenericTreeItem *child = (wxGenericTreeItem*)node->Data(); -#if 0 // VZ: don't delete items when the branch is collapsed - child->SendDelete( this ); - delete node; - node = i->m_children.First(); -#else if ( child->IsExpanded() ) ExpandItem( child->m_itemId, wxTREE_EXPAND_COLLAPSE ); node = node->Next(); -#endif }; + CalculatePositions(); + i->SendCollapse( this ); break; } @@ -607,19 +602,18 @@ bool wxTreeCtrl::ExpandItem( long item, int action ) } }; + wxClientDC dc(this); + PrepareDC(dc); + int cw = 0; int ch = 0; GetClientSize( &cw, &ch ); + wxRect rect; - rect.x = 0; + rect.x = dc.LogicalToDeviceX( 0 ); rect.width = cw; - wxClientDC dc(this); - PrepareDC(dc); rect.y = dc.LogicalToDeviceY( i->m_y ); - - long doY = 0; - dc.GetDeviceOrigin( NULL, &doY ); - rect.height = ch-rect.y-doY; + rect.height = ch; Refresh( TRUE, &rect ); AdjustMyScrollbars(); @@ -631,7 +625,19 @@ void wxTreeCtrl::DeleteItem( long item ) { wxGenericTreeItem *pItem = FindItem( item ); wxCHECK_RET( pItem != NULL, "wxTreeCtrl::DeleteItem: no such pItem." ); + pItem->m_parent->m_children.DeleteObject(pItem); + + Refresh(); +} + +void wxTreeCtrl::DeleteChildren( long item ) +{ + wxGenericTreeItem *pItem = FindItem( item ); + wxCHECK_RET( pItem != NULL, "wxTreeCtrl::DeleteChildren: no such pItem." ); + + pItem->m_children.Clear(); + Refresh(); } @@ -688,14 +694,40 @@ long wxTreeCtrl::GetRootItem() const long wxTreeCtrl::GetSelection() const { - return 0; + return m_current ? m_current->GetItemId() : -1; }; -bool wxTreeCtrl::SelectItem( long WXUNUSED(item) ) const +bool wxTreeCtrl::SelectItem(long itemId) { - return FALSE; + wxGenericTreeItem *pItem = FindItem(itemId); + if ( !pItem ) { + wxLogDebug("Can't select an item %d which doesn't exist.", itemId); + + return FALSE; + } + + SelectItem(pItem); + + return TRUE; }; +void wxTreeCtrl::SelectItem(wxGenericTreeItem *item) +{ + if (m_current != item) + { + if (m_current) + { + m_current->SetHilight( FALSE ); + RefreshLine( m_current ); + }; + m_current = item; + m_current->SetHilight( TRUE ); + RefreshLine( m_current ); + + m_current->SendSelected( this ); + } +} + bool wxTreeCtrl::ItemHasChildren( long item ) const { wxGenericTreeItem *i = FindItem( item ); @@ -757,6 +789,26 @@ long wxTreeCtrl::HitTest( const wxPoint& point, int &flags ) return m_anchor->HitTest( point, flags ); }; +wxImageList *wxTreeCtrl::GetImageList( int which ) const +{ + if (which == wxIMAGE_LIST_NORMAL) return m_imageList; + return m_smallImageList; +}; + +void wxTreeCtrl::SetImageList( wxImageList *imageList, int which ) +{ + if (which == wxIMAGE_LIST_NORMAL) + { + if (m_imageList) delete m_imageList; + m_imageList = imageList; + } + else + { + if (m_smallImageList) delete m_smallImageList; + m_smallImageList = imageList; + }; +}; + void wxTreeCtrl::AdjustMyScrollbars() { if (m_anchor) @@ -777,105 +829,107 @@ void wxTreeCtrl::AdjustMyScrollbars() void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y ) { - int horizX = level*m_indent+10; - int oldY = y; - wxNode *node = item->m_children.First(); - while (node) - { - wxGenericTreeItem *child = (wxGenericTreeItem *)node->Data(); - dc.SetPen( m_dottedPen ); + int horizX = level*m_indent; - child->SetCross( horizX+15, y ); + item->m_x = horizX+33; + item->m_y = y-m_lineHeight/3; + item->m_height = m_lineHeight; - if (!node->Next()) - { - if (level != 0) oldY -= (m_lineHeight-5); - dc.DrawLine( horizX, oldY, horizX, y ); - }; + item->SetCross( horizX+15, y ); - child->m_x = horizX+33; - child->m_y = y-m_lineHeight/3; - child->m_height = m_lineHeight; + int oldY = y; - if (IsExposed( 0, child->m_y-2, 10000, m_lineHeight+4 )) - { - int startX = horizX, - endX = horizX + 10; + int exposed_x = dc.LogicalToDeviceX( 0 ); + int exposed_y = dc.LogicalToDeviceY( item->m_y-2 ); + + if (IsExposed( exposed_x, exposed_y, 1000, m_lineHeight+4 )) + { + int startX = horizX; + int endX = horizX + 10; - if (!(node->Previous()) && (level == 0)) - startX -= 10; - if (!child->HasChildren()) - endX += 20; - dc.DrawLine( startX, y, endX, y ); + if (!item->HasChildren()) endX += 20; + + dc.DrawLine( startX, y, endX, y ); - if (child->HasChildren()) + if (item->HasChildren()) { dc.DrawLine( horizX+20, y, horizX+30, y ); dc.SetPen( *wxGREY_PEN ); dc.DrawRectangle( horizX+10, y-4, 11, 9 ); dc.SetPen( *wxBLACK_PEN ); - dc.DrawLine( horizX+13, y, horizX+17, y ); - if (child->HasPlus()) - dc.DrawLine( horizX+15, y-2, horizX+15, y+2 ); + dc.DrawLine( horizX+13, y, horizX+18, y ); + if (item->HasPlus()) + dc.DrawLine( horizX+15, y-2, horizX+15, y+3 ); }; - if (child->HasHilight()) + if (item->HasHilight()) { dc.SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) ); -#if 0 // VZ: this code leaves horizontal stripes when item is unselected dc.SetBrush( *m_hilightBrush ); + long tw, th; + dc.GetTextExtent( item->m_text, &tw, &th ); if (m_hasFocus) - dc.SetPen( wxBLACK_PEN ); + { + dc.SetPen( *wxBLACK_PEN ); + dc.DrawRectangle( item->m_x-2, item->m_y-2, tw+4, th+4 ); + } else - dc.SetPen( wxTRANSPARENT_PEN ); - long tw, th; - dc.GetTextExtent( child->m_text, &tw, &th ); - dc.DrawRectangle( child->m_x-2, child->m_y-2, tw+4, th+4 ); -#else - int modeOld = dc.GetBackgroundMode(); - dc.SetTextBackground( *wxBLACK ); - dc.SetBackgroundMode(wxSOLID); -#endif // 0 - - dc.DrawText( child->m_text, child->m_x, child->m_y ); + { + dc.SetPen( *wxTRANSPARENT_PEN ); + dc.DrawRectangle( item->m_x-2, item->m_y-2, tw+4, th+4 ); + } + dc.DrawText( item->m_text, item->m_x, item->m_y ); -#if 0 // VZ: same as above dc.SetPen( *wxBLACK_PEN ); -#else - dc.SetBackgroundMode(modeOld); - dc.SetTextBackground( *wxWHITE ); - dc.SetBrush( *wxWHITE_BRUSH ); -#endif dc.SetTextForeground( *wxBLACK ); + dc.SetBrush( *wxWHITE_BRUSH ); } else - dc.DrawText( child->m_text, child->m_x, child->m_y ); - }; + { + dc.SetBrush( *wxWHITE_BRUSH ); + dc.SetPen( *wxTRANSPARENT_PEN ); + long tw, th; + dc.GetTextExtent( item->m_text, &tw, &th ); + dc.DrawRectangle( item->m_x-2, item->m_y-2, tw+4, th+4 ); + dc.DrawText( item->m_text, item->m_x, item->m_y ); + dc.SetPen( *wxBLACK_PEN ); + }; + }; + + if (item->NumberOfVisibleChildren() == 0) return; + + int semiOldY = y; + + wxNode *node = item->m_children.First(); + while (node) + { + wxGenericTreeItem *child = (wxGenericTreeItem *)node->Data(); y += m_lineHeight; - if ( child->IsExpanded() && child->NumberOfVisibleChildren() > 0) - PaintLevel( child, dc, level+1, y ); + semiOldY = y; + + PaintLevel( child, dc, level+1, y ); + node = node->Next(); }; -}; + + dc.DrawLine( horizX+15, oldY+5, horizX+15, semiOldY ); +} void wxTreeCtrl::OnPaint( const wxPaintEvent &WXUNUSED(event) ) { if (!m_anchor) return; - if (!m_dc) - { - m_dc = new wxPaintDC(this); - PrepareDC( *m_dc ); - }; + wxPaintDC dc(this); + PrepareDC( dc ); - m_dc->SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) ); + dc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) ); - m_dc->SetPen( m_dottedPen ); - m_lineHeight = (int)(m_dc->GetCharHeight() + 4); + dc.SetPen( m_dottedPen ); + m_lineHeight = (int)(dc.GetCharHeight() + 4); int y = m_lineHeight / 2 + 2; - PaintLevel( m_anchor, *m_dc, 0, y ); + PaintLevel( m_anchor, dc, 0, y ); }; void wxTreeCtrl::OnSetFocus( const wxFocusEvent &WXUNUSED(event) ) @@ -915,18 +969,7 @@ void wxTreeCtrl::OnMouse( const wxMouseEvent &event ) if ((flag != wxTREE_HITTEST_ONITEMBUTTON) && (flag != wxTREE_HITTEST_ONITEMLABEL)) return; - if (m_current != item) - { - if (m_current) - { - m_current->SetHilight( FALSE ); - RefreshLine( m_current ); - }; - m_current = item; - m_current->SetHilight( TRUE ); - RefreshLine( m_current ); - m_current->SendSelected( this ); - }; + SelectItem(item); if (event.LeftDClick()) m_current->SendKeyDown( this ); @@ -940,28 +983,21 @@ void wxTreeCtrl::OnMouse( const wxMouseEvent &event ) void wxTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y ) { - int horizX = level*m_indent+10; + int horizX = level*m_indent; + + item->m_x = horizX+33; + item->m_y = y-m_lineHeight/3-2; + item->m_height = m_lineHeight; + + if (item->NumberOfVisibleChildren() == 0) return; + wxNode *node = item->m_children.First(); while (node) { wxGenericTreeItem *child = (wxGenericTreeItem *)node->Data(); - dc.SetPen( m_dottedPen ); - - int startX = horizX, - endX = horizX + 10; - - if (!node->Previous() && (level == 0)) - startX -= 10; - if (!child->HasChildren()) - endX += 20; - - child->m_x = horizX+33; - child->m_y = y-m_lineHeight/3-2; - child->m_height = m_lineHeight; y += m_lineHeight; - if ( child->IsExpanded() && child->NumberOfVisibleChildren() > 0 ) - CalculateLevel( child, dc, level+1, y ); + CalculateLevel( child, dc, level+1, y ); node = node->Next(); }; @@ -999,7 +1035,7 @@ void wxTreeCtrl::RefreshLine( wxGenericTreeItem *item ) rect.x = dc.LogicalToDeviceX( item->m_x-2 ); rect.y = dc.LogicalToDeviceY( item->m_y-2 ); rect.width = 1000; - rect.height = dc.GetCharHeight()+4; + rect.height = dc.GetCharHeight()+6; Refresh( TRUE, &rect ); };