From 74bedbeb40183e194948acf3d3308653623db4ec Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 1 Jul 1998 15:42:11 +0000 Subject: [PATCH] many changes to make generic tree control (more) MSW compatible: 1) wxEVT_COMMAND_TREE_EXPANDING event now generated 2) tree control doesn't not delete children on branch collapse any more 3) migging image list and image-related functions added (but not yet implemented) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@160 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/treectrl.h | 70 ++++++------- src/generic/treectrl.cpp | 179 ++++++++++++++++++++++------------ 2 files changed, 153 insertions(+), 96 deletions(-) diff --git a/include/wx/generic/treectrl.h b/include/wx/generic/treectrl.h index 1f5b3f3fe0..23bac6bddc 100644 --- a/include/wx/generic/treectrl.h +++ b/include/wx/generic/treectrl.h @@ -35,6 +35,8 @@ class wxTreeEvent; class wxGenericTreeItem; class wxTreeCtrl; +class wxImageList; + //----------------------------------------------------------------------------- // constants //----------------------------------------------------------------------------- @@ -153,7 +155,7 @@ class WXDLLEXPORT wxTreeItem: public wxObject inline void SetStateMask(long stateMask) { m_stateMask = stateMask; } inline void GetText(const wxString& text) { m_text = text; } inline void SetImage(int image) { m_image = image; } - inline void GetSelectedImage(int selImage) { m_selectedImage = selImage; } + inline void SetSelectedImage(int selImage) { m_selectedImage = selImage; } inline void SetChildren(int children) { m_children = children; } inline void SetData(long data) { m_data = data; } }; @@ -177,6 +179,7 @@ class WXDLLEXPORT wxTreeEvent: public wxCommandEvent inline long GetOldItem() const { return m_oldItem; } inline wxTreeItem& GetItem() const { return (wxTreeItem&) m_item; } inline wxPoint GetPoint() const { return m_pointDrag; } + inline void SetCode(int code) { m_code = code; } inline int GetCode() const { return m_code; } }; @@ -199,20 +202,13 @@ typedef void (wxEvtHandler::*wxTreeEventFunction)(wxTreeEvent&); // wxGenericTreeItem //----------------------------------------------------------------------------- -class WXDLLEXPORT wxGenericTreeItem: public wxObject +class WXDLLEXPORT wxGenericTreeItem: public wxTreeItem { DECLARE_DYNAMIC_CLASS(wxGenericTreeItem) - - public: - long m_itemId; - long m_state; - wxString m_text; - int m_image; - int m_selectedImage; -// int m_children; - bool m_hasChildren; - long m_data; + public: + bool m_hasChildren, + m_isCollapsed; int m_x,m_y; int m_height,m_width; @@ -221,7 +217,7 @@ class WXDLLEXPORT wxGenericTreeItem: public wxObject wxList m_children; wxGenericTreeItem *m_parent; bool m_hasHilight; - + wxGenericTreeItem(void) {}; wxGenericTreeItem( wxGenericTreeItem *parent ); wxGenericTreeItem( wxGenericTreeItem *parent, const wxTreeItem& item, wxDC *dc ); @@ -244,8 +240,10 @@ class WXDLLEXPORT wxGenericTreeItem: public wxObject void SendSelected( wxWindow *target ); void SendDelete( wxWindow *target ); void SendExpand( wxWindow *target ); + void SendCollapse( wxWindow *target ); void SetHilight( bool set = TRUE ); bool HasHilight(void); + bool IsExpanded() const { return !m_isCollapsed; } }; //----------------------------------------------------------------------------- @@ -255,41 +253,43 @@ class WXDLLEXPORT wxGenericTreeItem: public wxObject class wxTreeCtrl: public wxScrolledWindow { DECLARE_DYNAMIC_CLASS(wxTreeCtrl) - + public: - + wxTreeCtrl(void); wxTreeCtrl(wxWindow *parent, const wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - const long style = wxTR_HAS_BUTTONS, + long style = wxTR_HAS_BUTTONS, const wxString& name = "wxTreeCtrl" ); ~wxTreeCtrl(void); bool Create(wxWindow *parent, const wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - const long style = wxTR_HAS_BUTTONS, + long style = wxTR_HAS_BUTTONS, const wxString& name = "wxTreeCtrl"); int GetCount(void) const; - long InsertItem( const long parent, const wxString& label, const int image = -1, - const int selImage = -1, const long insertAfter = wxTREE_INSERT_LAST ); - long InsertItem( const long parent, wxTreeItem &info, const long insertAfter = wxTREE_INSERT_LAST ); + long InsertItem( long parent, const wxString& label, const int image = -1, + const int selImage = -1, long insertAfter = wxTREE_INSERT_LAST ); + long InsertItem( long parent, wxTreeItem &info, long insertAfter = wxTREE_INSERT_LAST ); bool DeleteAllItems(void); - bool ExpandItem( const long item, const int action ); + bool ExpandItem( long item, const int action ); bool GetItem( wxTreeItem &info ) const; - long GetItemData( const long item ) const; - wxString GetItemText( const long item ) const; - long GetParent( const long item ) const; + long GetItemData( long item ) const; + wxString GetItemText( long item ) const; + int GetItemImage(long item) const; + long GetParent( long item ) const; long GetRootItem(void) const; long GetSelection(void) const; - bool SelectItem( const long item ) const; - bool ItemHasChildren( const long item ) const; + bool SelectItem( long item ) const; + bool ItemHasChildren( long item ) const; void SetIndent( const int indent ); int GetIndent(void) const; bool SetItem( wxTreeItem &info ); - bool SetItemData( const long item, const long data ); - bool SetItemText( const long item, const wxString &text ); + bool SetItemData( long item, long data ); + bool SetItemText( long item, const wxString &text ); + void SetItemImage(long item, int image, int imageSel) const; long HitTest( const wxPoint& point, int &flags ); void AdjustMyScrollbars(void); @@ -299,9 +299,12 @@ class wxTreeCtrl: public wxScrolledWindow void OnKillFocus( const wxFocusEvent &event ); void OnChar( wxKeyEvent &event ); void OnMouse( const wxMouseEvent &event ); - + + void SetImageList(wxImageList *imageList) { m_imageList = imageList; } + wxImageList *GetImageList() const { return m_imageList; } + private: - + wxGenericTreeItem *m_anchor; wxGenericTreeItem *m_current; bool m_hasFocus; @@ -312,13 +315,14 @@ class wxTreeCtrl: public wxScrolledWindow wxPen m_dottedPen; bool m_isCreated; wxPaintDC *m_dc; - wxBrush *m_hilightBrush; + wxBrush *m_hilightBrush; + wxImageList *m_imageList; void CalculateLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y ); void CalculatePositions(void); - wxGenericTreeItem *FindItem( const long itemId ) const; + wxGenericTreeItem *FindItem( long itemId ) const; void RefreshLine( wxGenericTreeItem *item ); - + DECLARE_EVENT_TABLE() }; diff --git a/src/generic/treectrl.cpp b/src/generic/treectrl.cpp index 427e182d4d..0a375375e7 100644 --- a/src/generic/treectrl.cpp +++ b/src/generic/treectrl.cpp @@ -21,7 +21,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxTreeItem, wxObject) -wxTreeItem::wxTreeItem(void) +wxTreeItem::wxTreeItem() { m_mask = 0; m_itemId = 0; @@ -100,7 +100,7 @@ void wxGenericTreeItem::SetText( const wxString &text, wxDC *dc ) m_height = lh; }; -void wxGenericTreeItem::Reset(void) +void wxGenericTreeItem::Reset() { m_itemId = -1; m_state = 0; @@ -118,6 +118,7 @@ void wxGenericTreeItem::Reset(void) m_yCross = 0; m_level = 0; m_children.DeleteContents( TRUE ); + m_isCollapsed = TRUE; m_parent = NULL; }; @@ -137,17 +138,20 @@ void wxGenericTreeItem::GetItem( wxTreeItem &item ) const item.m_data = m_data; }; -bool wxGenericTreeItem::HasChildren(void) +bool wxGenericTreeItem::HasChildren() { return m_hasChildren; }; -bool wxGenericTreeItem::HasPlus(void) +bool wxGenericTreeItem::HasPlus() { - return (m_hasChildren && (m_children.Number() == 0)); + if ( !HasChildren() ) + return FALSE; + + return !IsExpanded(); }; -int wxGenericTreeItem::NumberOfVisibleDescendents(void) +int wxGenericTreeItem::NumberOfVisibleDescendents() { int ret = m_children.Number(); wxNode *node = m_children.First(); @@ -160,9 +164,9 @@ int wxGenericTreeItem::NumberOfVisibleDescendents(void) return ret; }; -int wxGenericTreeItem::NumberOfVisibleChildren(void) +int wxGenericTreeItem::NumberOfVisibleChildren() { - return m_children.Number(); + return m_isCollapsed ? 0 : m_children.Number(); }; wxGenericTreeItem *wxGenericTreeItem::FindItem( long itemId ) const @@ -277,8 +281,7 @@ void wxGenericTreeItem::SendSelected( wxWindow *target ) void wxGenericTreeItem::SendDelete( wxWindow *target ) { - wxTreeEvent event( wxEVT_COMMAND_TREE_DELETE_ITEM, - target->GetId() ); + wxTreeEvent event( wxEVT_COMMAND_TREE_DELETE_ITEM, target->GetId() ); PrepareEvent( event ); event.SetEventObject( target ); target->ProcessEvent( event ); @@ -286,10 +289,31 @@ void wxGenericTreeItem::SendDelete( wxWindow *target ) void wxGenericTreeItem::SendExpand( wxWindow *target ) { - wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDED, - target->GetId() ); - PrepareEvent( event ); + 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 ); + + event.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED); + PrepareEvent( event ); + target->ProcessEvent( event ); +}; + +void wxGenericTreeItem::SendCollapse( wxWindow *target ) +{ + m_isCollapsed = TRUE; + + wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, target->GetId() ); + event.SetCode(wxTREE_EXPAND_COLLAPSE); + event.SetEventObject( target ); + PrepareEvent( event ); + target->ProcessEvent( event ); + + event.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED); + PrepareEvent( event ); target->ProcessEvent( event ); }; @@ -298,7 +322,7 @@ void wxGenericTreeItem::SetHilight( bool set ) m_hasHilight = set; }; -bool wxGenericTreeItem::HasHilight(void) +bool wxGenericTreeItem::HasHilight() { return m_hasHilight; }; @@ -318,7 +342,7 @@ BEGIN_EVENT_TABLE(wxTreeCtrl,wxScrolledWindow) EVT_KILL_FOCUS (wxTreeCtrl::OnKillFocus) END_EVENT_TABLE() -wxTreeCtrl::wxTreeCtrl(void) +wxTreeCtrl::wxTreeCtrl() { m_current = NULL; m_anchor = NULL; @@ -336,7 +360,7 @@ wxTreeCtrl::wxTreeCtrl(void) wxTreeCtrl::wxTreeCtrl(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, - const long style, const wxString& name ) + long style, const wxString& name ) { m_current = NULL; m_anchor = NULL; @@ -352,7 +376,7 @@ wxTreeCtrl::wxTreeCtrl(wxWindow *parent, const wxWindowID id, Create( parent, id, pos, size, style, name ); }; -wxTreeCtrl::~wxTreeCtrl(void) +wxTreeCtrl::~wxTreeCtrl() { if (m_dc) delete m_dc; }; @@ -360,7 +384,7 @@ wxTreeCtrl::~wxTreeCtrl(void) bool wxTreeCtrl::Create(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, - const long style + long style , const wxString& name ) { wxScrolledWindow::Create( parent, id, pos, size, style, name ); @@ -369,14 +393,14 @@ bool wxTreeCtrl::Create(wxWindow *parent, const wxWindowID id, return TRUE; }; -int wxTreeCtrl::GetCount(void) const +int wxTreeCtrl::GetCount() const { if (!m_anchor) return 0; return m_anchor->NumberOfVisibleDescendents(); }; -long wxTreeCtrl::InsertItem( const long parent, const wxString& label, const int image, - const int selImage, const long WXUNUSED(insertAfter) ) +long wxTreeCtrl::InsertItem( long parent, const wxString& label, int image, + int selImage, long WXUNUSED(insertAfter) ) { wxGenericTreeItem *p = NULL; if (parent == 0) @@ -457,7 +481,7 @@ long wxTreeCtrl::InsertItem( const long parent, const wxString& label, const int return m_lastId; }; -long wxTreeCtrl::InsertItem( const long parent, wxTreeItem &info, const long WXUNUSED(insertAfter) ) +long wxTreeCtrl::InsertItem( long parent, wxTreeItem &info, long WXUNUSED(insertAfter) ) { int oldMask = info.m_mask; wxGenericTreeItem *p = NULL; @@ -537,17 +561,20 @@ long wxTreeCtrl::InsertItem( const long parent, wxTreeItem &info, const long WXU return ret; }; -bool wxTreeCtrl::ExpandItem( const long item, const int action ) +bool wxTreeCtrl::ExpandItem( long item, int action ) { wxGenericTreeItem *i = FindItem( item ); - if (!i) return FALSE; + if (!i) + return FALSE; + switch (action) { case wxTREE_EXPAND_EXPAND: { i->SendExpand( this ); break; - }; + } + case wxTREE_EXPAND_COLLAPSE_RESET: case wxTREE_EXPAND_COLLAPSE: { @@ -555,42 +582,52 @@ bool wxTreeCtrl::ExpandItem( const long item, const 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 }; - int cw = 0; - int ch = 0; - GetClientSize( &cw, &ch ); - wxRect rect; - rect.x = 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; - Refresh( TRUE, &rect ); - - AdjustMyScrollbars(); + i->SendCollapse( this ); break; - }; + } + case wxTREE_EXPAND_TOGGLE: { - if (i->HasPlus()) - ExpandItem( item, wxTREE_EXPAND_EXPAND ); - else + if ( i->IsExpanded() ) ExpandItem( item, wxTREE_EXPAND_COLLAPSE ); - break; - }; + else + ExpandItem( item, wxTREE_EXPAND_EXPAND ); + return TRUE; + } }; + + int cw = 0; + int ch = 0; + GetClientSize( &cw, &ch ); + wxRect rect; + rect.x = 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; + Refresh( TRUE, &rect ); + + AdjustMyScrollbars(); + return TRUE; }; -bool wxTreeCtrl::DeleteAllItems(void) +bool wxTreeCtrl::DeleteAllItems() { delete m_anchor; m_anchor = NULL; @@ -606,21 +643,27 @@ bool wxTreeCtrl::GetItem( wxTreeItem &info ) const return TRUE; }; -long wxTreeCtrl::GetItemData( const long item ) const +long wxTreeCtrl::GetItemData( long item ) const { wxGenericTreeItem *i = FindItem( item ); if (!i) return 0; return i->m_data; }; -wxString wxTreeCtrl::GetItemText( const long item ) const +wxString wxTreeCtrl::GetItemText( long item ) const { wxGenericTreeItem *i = FindItem( item ); if (!i) return ""; return i->m_text; }; -long wxTreeCtrl::GetParent( const long item ) const +int wxTreeCtrl::GetItemImage(long item) const +{ + wxGenericTreeItem *i = FindItem( item ); + return i == 0 ? -1 : i->GetImage(); +} + +long wxTreeCtrl::GetParent( long item ) const { wxGenericTreeItem *i = FindItem( item ); if (!i) return -1; @@ -629,36 +672,36 @@ long wxTreeCtrl::GetParent( const long item ) const return i->m_parent->m_itemId; }; -long wxTreeCtrl::GetRootItem(void) const +long wxTreeCtrl::GetRootItem() const { if (m_anchor) return m_anchor->m_itemId; return -1; }; -long wxTreeCtrl::GetSelection(void) const +long wxTreeCtrl::GetSelection() const { return 0; }; -bool wxTreeCtrl::SelectItem( const long WXUNUSED(item) ) const +bool wxTreeCtrl::SelectItem( long WXUNUSED(item) ) const { return FALSE; }; -bool wxTreeCtrl::ItemHasChildren( const long item ) const +bool wxTreeCtrl::ItemHasChildren( long item ) const { wxGenericTreeItem *i = FindItem( item ); if (!i) return FALSE; return i->m_hasChildren; }; -void wxTreeCtrl::SetIndent( const int indent ) +void wxTreeCtrl::SetIndent( int indent ) { m_indent = indent; Refresh(); }; -int wxTreeCtrl::GetIndent(void) const +int wxTreeCtrl::GetIndent() const { return m_indent; }; @@ -669,10 +712,11 @@ bool wxTreeCtrl::SetItem( wxTreeItem &info ) if (!i) return FALSE; wxClientDC dc(this); i->SetItem( info, &dc ); + Refresh(); return TRUE; }; -bool wxTreeCtrl::SetItemData( const long item, const long data ) +bool wxTreeCtrl::SetItemData( long item, long data ) { wxGenericTreeItem *i = FindItem( item ); if (!i) return FALSE; @@ -680,7 +724,7 @@ bool wxTreeCtrl::SetItemData( const long item, const long data ) return TRUE; }; -bool wxTreeCtrl::SetItemText( const long item, const wxString &text ) +bool wxTreeCtrl::SetItemText( long item, const wxString &text ) { wxGenericTreeItem *i = FindItem( item ); if (!i) return FALSE; @@ -689,6 +733,15 @@ bool wxTreeCtrl::SetItemText( const long item, const wxString &text ) return TRUE; }; +void wxTreeCtrl::SetItemImage(long item, int image, int imageSel) const +{ + wxGenericTreeItem *i = FindItem( item ); + if ( i != 0 ) { + i->SetImage(image); + i->SetSelectedImage(imageSel); + } +} + long wxTreeCtrl::HitTest( const wxPoint& point, int &flags ) { flags = 0; @@ -696,7 +749,7 @@ long wxTreeCtrl::HitTest( const wxPoint& point, int &flags ) return m_anchor->HitTest( point, flags ); }; -void wxTreeCtrl::AdjustMyScrollbars(void) +void wxTreeCtrl::AdjustMyScrollbars() { if (m_anchor) { @@ -792,7 +845,7 @@ void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, }; y += m_lineHeight; - if (child->NumberOfVisibleChildren() > 0) + if ( child->IsExpanded() && child->NumberOfVisibleChildren() > 0) PaintLevel( child, dc, level+1, y ); node = node->Next(); }; @@ -899,14 +952,14 @@ void wxTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxPaintDC &dc, int lev child->m_height = m_lineHeight; y += m_lineHeight; - if (child->NumberOfVisibleChildren() > 0) + if ( child->IsExpanded() && child->NumberOfVisibleChildren() > 0 ) CalculateLevel( child, dc, level+1, y ); node = node->Next(); }; }; -void wxTreeCtrl::CalculatePositions(void) +void wxTreeCtrl::CalculatePositions() { if (!m_anchor) return;