some new functions:

1. wxTreeItemData::SetId() added
 2. wxTreeCtrl::SetItemHasChildren() added


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@908 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1998-10-24 23:53:20 +00:00
parent 32e9da8bfa
commit 3a5a2f56f2
3 changed files with 192 additions and 304 deletions

View File

@@ -131,27 +131,19 @@ protected:
// Because the objects of this class are deleted by the tree, they should // Because the objects of this class are deleted by the tree, they should
// always be allocated on the heap! // always be allocated on the heap!
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class WXDLLEXPORT wxTreeItemData class WXDLLEXPORT wxTreeItemData : private wxTreeItemId
{ {
friend class wxTreeCtrl;
public: public:
// creation/destruction // default ctor/copy ctor/assignment operator are ok
// --------------------
// default ctor
wxTreeItemData() { }
// default copy ctor/assignment operator are ok // dtor is virtual and all the items are deleted by the tree control when
// it's deleted, so you normally don't have to care about freeing memory
// dtor is virtual and all the items are deleted by the tree control // allocated in your wxTreeItemData-derived class
// when it's deleted, so you normally don't have to care about freeing
// memory allocated in your wxTreeItemData-derived class
virtual ~wxTreeItemData() { } virtual ~wxTreeItemData() { }
// accessor: get the item associated with us // accessors: set/get the item associated with this node
const wxTreeItemId& GetItemId() const { return m_itemId; } void SetId(const wxTreeItemId& id) { m_itemId = id; }
const wxTreeItemId& GetId() const { return m_itemId; }
protected:
wxTreeItemId m_itemId;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -240,6 +232,12 @@ public:
// associate some data with the item // associate some data with the item
void SetItemData(const wxTreeItemId& item, wxTreeItemData *data); void SetItemData(const wxTreeItemId& item, wxTreeItemData *data);
// force appearance of [+] button near the item. This is useful to
// allow the user to expand the items which don't have any children now
// - but instead add them only when needed, thus minimizing memory
// usage and loading time.
void SetItemHasChildren(const wxTreeItemId& item, bool has = TRUE);
// item status inquiries // item status inquiries
// --------------------- // ---------------------

View File

@@ -6,53 +6,59 @@
// Created: 04/01/98 // Created: 04/01/98
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem // Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license // Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation #pragma implementation
#pragma interface #pragma interface
#endif #endif
// For compilers that support precompilation, includes "wx/wx.h". // For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h" #include "wx/wxprec.h"
#ifdef __BORLANDC__ #ifdef __BORLANDC__
#pragma hdrstop #pragma hdrstop
#endif #endif
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/wx.h" #include "wx/wx.h"
#endif #endif
// under Windows the icons are in the .rc file
#ifndef __WXMSW__ #ifndef __WXMSW__
#include "icon1.xpm" #include "icon1.xpm"
#include "icon2.xpm" #include "icon2.xpm"
#include "mondrian.xpm" #include "mondrian.xpm"
#endif #endif
#include "wx/log.h"
#include "wx/imaglist.h"
#include "wx/treectrl.h" #include "wx/treectrl.h"
#include "treetest.h" #include "treetest.h"
BEGIN_EVENT_TABLE(MyFrame, wxFrame) BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(TREE_QUIT, MyFrame::OnQuit) EVT_MENU(TreeTest_Quit, MyFrame::OnQuit)
EVT_MENU(TREE_ABOUT, MyFrame::OnAbout) EVT_MENU(TreeTest_About, MyFrame::OnAbout)
END_EVENT_TABLE() END_EVENT_TABLE()
BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl) BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)
EVT_TREE_BEGIN_DRAG(TREE_CTRL, MyTreeCtrl::OnBeginDrag) EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginDrag)
EVT_TREE_BEGIN_RDRAG(TREE_CTRL, MyTreeCtrl::OnBeginRDrag) EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginRDrag)
EVT_TREE_BEGIN_LABEL_EDIT(TREE_CTRL, MyTreeCtrl::OnBeginLabelEdit) EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnBeginLabelEdit)
EVT_TREE_END_LABEL_EDIT(TREE_CTRL, MyTreeCtrl::OnEndLabelEdit) EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnEndLabelEdit)
EVT_TREE_DELETE_ITEM(TREE_CTRL, MyTreeCtrl::OnDeleteItem) EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, MyTreeCtrl::OnDeleteItem)
EVT_TREE_GET_INFO(TREE_CTRL, MyTreeCtrl::OnGetInfo) EVT_TREE_GET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnGetInfo)
EVT_TREE_SET_INFO(TREE_CTRL, MyTreeCtrl::OnSetInfo) EVT_TREE_SET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnSetInfo)
EVT_TREE_ITEM_EXPANDED(TREE_CTRL, MyTreeCtrl::OnItemExpanded) EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanded)
EVT_TREE_ITEM_EXPANDING(TREE_CTRL, MyTreeCtrl::OnItemExpanding) EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanding)
EVT_TREE_SEL_CHANGED(TREE_CTRL, MyTreeCtrl::OnSelChanged) EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, MyTreeCtrl::OnItemCollapsed)
EVT_TREE_SEL_CHANGING(TREE_CTRL, MyTreeCtrl::OnSelChanging) EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, MyTreeCtrl::OnItemCollapsing)
EVT_TREE_KEY_DOWN(TREE_CTRL, MyTreeCtrl::OnKeyDown) EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, MyTreeCtrl::OnSelChanged)
EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, MyTreeCtrl::OnSelChanging)
EVT_TREE_KEY_DOWN(TreeTest_Ctrl, MyTreeCtrl::OnKeyDown)
END_EVENT_TABLE() END_EVENT_TABLE()
IMPLEMENT_APP(MyApp) IMPLEMENT_APP(MyApp)
@@ -61,320 +67,198 @@ IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() bool MyApp::OnInit()
{ {
// Create the main frame window // Create the main frame window
MyFrame *frame = new MyFrame((wxFrame *) NULL, (char *) "wxTreeCtrl Test", 50, 50, 450, 340); MyFrame *frame = new MyFrame("wxTreeCtrl Test", 50, 50, 450, 340);
// This reduces flicker effects - even better would be to define OnEraseBackground
// to do nothing. When the tree control's scrollbars are show or hidden, the
// frame is sent a background erase event.
frame->SetBackgroundColour(wxColour(255, 255, 255));
// Give it an icon
frame->SetIcon(wxICON(mondrian));
// Make an image list containing small icons
m_imageListNormal = new wxImageList(16, 16, TRUE);
m_imageListNormal->Add(wxICON(icon1));
m_imageListNormal->Add(wxICON(icon2));
// Make a menubar
wxMenu *file_menu = new wxMenu;
file_menu->Append(TREE_ABOUT, "&About");
file_menu->Append(TREE_QUIT, "E&xit");
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
frame->SetMenuBar(menu_bar);
// Make a panel with a message
frame->m_treeCtrl = new MyTreeCtrl(frame, TREE_CTRL, wxPoint(0, 0), wxSize(400, 200),
wxTR_HAS_BUTTONS|wxSUNKEN_BORDER);
frame->m_logWindow = new wxTextCtrl(frame, -1, "", wxPoint(0, 0), wxSize(400, 200),
wxTE_MULTILINE|wxSUNKEN_BORDER);
wxLayoutConstraints *c = new wxLayoutConstraints;
c->top.SameAs (frame, wxTop);
c->left.SameAs (frame, wxLeft);
c->right.SameAs (frame, wxRight);
c->height.PercentOf (frame, wxHeight, 66);
frame->m_treeCtrl->SetConstraints(c);
c = new wxLayoutConstraints;
c->top.Below (frame->m_treeCtrl);
c->left.SameAs (frame, wxLeft);
c->right.SameAs (frame, wxRight);
c->bottom.SameAs (frame, wxBottom);
frame->m_logWindow->SetConstraints(c);
frame->SetAutoLayout(TRUE);
frame->m_treeCtrl->SetImageList(wxGetApp().m_imageListNormal, wxIMAGE_LIST_NORMAL);
wxTreeItemId rootId = frame->m_treeCtrl->AddRoot("Root", 0);
char buf[20];
int i;
wxString str;
for ( i = 0; i < 10; i++)
{
sprintf(buf, "Folder child %d", i);
str = buf;
wxTreeItemId id = frame->m_treeCtrl->AppendItem(rootId, str, 0);
int j;
for ( j = 0; j < 5; j++)
{
sprintf(buf, "File child %d", j);
str = buf;
frame->m_treeCtrl->AppendItem(id, str, 1);
}
}
for ( i = 0; i < 10; i++)
{
sprintf(buf, "File child %d", i);
str = buf;
frame->m_treeCtrl->AppendItem(rootId, str, 1);
}
frame->CreateStatusBar(3);
frame->SetStatusText("", 0);
// Show the frame // Show the frame
frame->Show(TRUE); frame->Show(TRUE);
SetTopWindow(frame); SetTopWindow(frame);
return TRUE; return TRUE;
} }
// My frame constructor // My frame constructor
MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h): MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h)) : wxFrame((wxFrame *)NULL, -1, title, wxPoint(x, y), wxSize(w, h))
{ {
m_treeCtrl = (MyTreeCtrl *) NULL; // This reduces flicker effects - even better would be to define
m_logWindow = (wxTextCtrl *) NULL; // OnEraseBackground to do nothing. When the tree control's scrollbars are
// show or hidden, the frame is sent a background erase event.
SetBackgroundColour(wxColour(255, 255, 255));
// Give it an icon
SetIcon(wxICON(mondrian));
// Make a menubar
wxMenu *file_menu = new wxMenu;
file_menu->Append(TreeTest_About, "&About...");
file_menu->Append(TreeTest_Quit, "E&xit");
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
SetMenuBar(menu_bar);
// Make a panel with a message
m_treeCtrl = new MyTreeCtrl(this, TreeTest_Ctrl,
wxDefaultPosition, wxDefaultSize,
wxTR_HAS_BUTTONS | wxSUNKEN_BORDER);
wxTextCtrl *textCtrl = new wxTextCtrl(this, -1, "",
wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxSUNKEN_BORDER);
wxLayoutConstraints *c = new wxLayoutConstraints;
c->top.SameAs(this, wxTop);
c->left.SameAs(this, wxLeft);
c->right.SameAs(this, wxRight);
c->height.PercentOf(this, wxHeight, 66);
m_treeCtrl->SetConstraints(c);
c = new wxLayoutConstraints;
c->top.Below(m_treeCtrl);
c->left.SameAs(this, wxLeft);
c->right.SameAs(this, wxRight);
c->bottom.SameAs(this, wxBottom);
textCtrl->SetConstraints(c);
SetAutoLayout(TRUE);
// create a status bar with 3 panes
CreateStatusBar(3);
SetStatusText("", 0);
// set our text control as the log target
wxLogTextCtrl *logWindow = new wxLogTextCtrl(textCtrl);
delete wxLog::SetActiveTarget(logWindow);
} }
MyFrame::~MyFrame() MyFrame::~MyFrame()
{ {
delete wxGetApp().m_imageListNormal; delete wxLog::SetActiveTarget(NULL);
} }
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{ {
Close(TRUE); Close(TRUE);
} }
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{ {
wxMessageDialog dialog(this, "Tree test sample\nJulian Smart (c) 1997", wxMessageDialog dialog(this, "Tree test sample\nJulian Smart (c) 1997",
"About tree test", wxOK|wxCANCEL); "About tree test", wxOK);
dialog.ShowModal(); dialog.ShowModal();
} }
// MyTreeCtrl // MyTreeCtrl implementation
MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
void MyTreeCtrl::OnBeginDrag(wxTreeEvent& WXUNUSED(event) ) const wxPoint& pos, const wxSize& size,
long style)
: wxTreeCtrl(parent, id, pos, size, style)
{ {
if ( !wxGetApp().GetTopWindow() ) // Make an image list containing small icons
return; m_imageListNormal = new wxImageList(16, 16, TRUE);
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow; // should correspond to TreeCtrlIcon_xxx enum
if ( !text ) m_imageListNormal->Add(wxICON(icon1));
return; m_imageListNormal->Add(wxICON(icon2));
#ifndef __GNUWIN32__ SetImageList(m_imageListNormal);
ostream str(text);
str << "OnBeginDrag\n"; // Add some items to the tree
str.flush(); AddTestItemsToTree(4, 3);
#endif
} }
void MyTreeCtrl::OnBeginRDrag(wxTreeEvent& WXUNUSED(event) ) MyTreeCtrl::~MyTreeCtrl()
{ {
if ( !wxGetApp().GetTopWindow() ) delete m_imageListNormal;
return;
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow;
if ( !text )
return;
#ifndef __GNUWIN32__
ostream str(text);
str << "OnBeginRDrag\n";
str.flush();
#endif
} }
void MyTreeCtrl::OnBeginLabelEdit(wxTreeEvent& WXUNUSED(event) ) void MyTreeCtrl::AddItemsRecursively(const wxTreeItemId& idParent,
size_t numChildren,
size_t depth)
{ {
if ( !wxGetApp().GetTopWindow() ) if ( depth > 0 )
return; {
wxString str;
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow; for ( size_t n = 0; n < numChildren; n++ )
if ( !text ) {
return; // at depth 1 elements won't have any more children
str.Printf("%s child %d", depth == 1 ? "File" : "Folder", n);
#ifndef __GNUWIN32__ int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;
ostream str(text); wxTreeItemId id = AppendItem(idParent, str, image, image,
new MyTreeItemData(str));
str << "OnBeginLabelEdit\n"; AddItemsRecursively(id, numChildren, depth - 1);
str.flush(); }
#endif }
//else: done!
} }
void MyTreeCtrl::OnEndLabelEdit(wxTreeEvent& WXUNUSED(event) ) void MyTreeCtrl::AddTestItemsToTree(size_t numChildren,
size_t depth)
{ {
if ( !wxGetApp().GetTopWindow() ) long rootId = AddRoot("Root",
return; TreeCtrlIcon_Folder, TreeCtrlIcon_Folder,
new MyTreeItemData("Root item"));
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow; AddItemsRecursively(rootId, numChildren, depth);
if ( !text )
return;
#ifndef __GNUWIN32__
ostream str(text);
str << "OnEndLabelEdit\n";
str.flush();
#endif
} }
void MyTreeCtrl::OnDeleteItem(wxTreeEvent& WXUNUSED(event) ) // avoid repetition
#define TREE_EVENT_HANDLER(name) \
void MyTreeCtrl::name(wxTreeEvent& WXUNUSED(event)) \
{ \
wxLogMessage(#name); \
}
TREE_EVENT_HANDLER(OnBeginDrag)
TREE_EVENT_HANDLER(OnBeginRDrag)
TREE_EVENT_HANDLER(OnBeginLabelEdit)
TREE_EVENT_HANDLER(OnEndLabelEdit)
TREE_EVENT_HANDLER(OnDeleteItem)
TREE_EVENT_HANDLER(OnGetInfo)
TREE_EVENT_HANDLER(OnSetInfo)
TREE_EVENT_HANDLER(OnItemExpanded)
TREE_EVENT_HANDLER(OnItemExpanding)
TREE_EVENT_HANDLER(OnItemCollapsed)
TREE_EVENT_HANDLER(OnSelChanged)
TREE_EVENT_HANDLER(OnSelChanging)
#undef TREE_EVENT_HANDLER
void MyTreeCtrl::OnItemCollapsing(wxTreeEvent& event)
{ {
if ( !wxGetApp().GetTopWindow() ) // for testing, prevent the user from collapsing the root item
return; wxTreeItemId itemId = event.GetItem();
if ( !GetParent(itemId).IsOk() )
{
wxMessageBox("Root item shouldn't collapse");
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow; event.Veto();
if ( !text ) }
return;
#ifndef __GNUWIN32__
ostream str(text);
str << "OnDeleteItem\n";
str.flush();
#endif
} }
void MyTreeCtrl::OnGetInfo(wxTreeEvent& WXUNUSED(event) ) void MyTreeCtrl::OnKeyDown(wxTreeEvent& event)
{ {
if ( !wxGetApp().GetTopWindow() ) // show some info about this item
return; wxTreeItemId itemId = GetSelection();
MyTreeItemData *item = (MyTreeItemData *)GetItemData(itemId);
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow; if ( item != NULL )
if ( !text ) {
return; item->ShowInfo(this);
}
#ifndef __GNUWIN32__ wxLogMessage("OnKeyDown");
ostream str(text);
str << "OnGetInfo\n";
str.flush();
#endif
} }
void MyTreeCtrl::OnSetInfo(wxTreeEvent& WXUNUSED(event) ) static inline const char *Bool2String(bool b)
{ {
if ( !wxGetApp().GetTopWindow() ) return b ? "" : "not ";
return;
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow;
if ( !text )
return;
#ifndef __GNUWIN32__
ostream str(text);
str << "OnSetInfo\n";
str.flush();
#endif
} }
void MyTreeCtrl::OnItemExpanded(wxTreeEvent& WXUNUSED(event) ) void MyTreeItemData::ShowInfo(wxTreeCtrl *tree)
{ {
if ( !wxGetApp().GetTopWindow() ) wxLogMessage("Item '%s': %sselected, %sexpanded.",
return; m_desc.c_str(),
Bool2String(tree->IsExpanded(m_itemId)),
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow; Bool2String(tree->IsSelected(m_itemId)));
if ( !text )
return;
#ifndef __GNUWIN32__
ostream str(text);
str << "OnItemExpanded\n";
str.flush();
#endif
} }
void MyTreeCtrl::OnItemExpanding(wxTreeEvent& WXUNUSED(event) )
{
if ( !wxGetApp().GetTopWindow() )
return;
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow;
if ( !text )
return;
#ifndef __GNUWIN32__
ostream str(text);
str << "OnItemExpanding\n";
str.flush();
#endif
}
void MyTreeCtrl::OnSelChanged(wxTreeEvent& WXUNUSED(event) )
{
if ( !wxGetApp().GetTopWindow() )
return;
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow;
if ( !text )
return;
#ifndef __GNUWIN32__
ostream str(text);
str << "OnSelChanged\n";
str.flush();
#endif
}
void MyTreeCtrl::OnSelChanging(wxTreeEvent& WXUNUSED(event) )
{
if ( !wxGetApp().GetTopWindow() )
return;
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow;
if ( !text )
return;
#ifndef __GNUWIN32__
ostream str(text);
str << "OnSelChanging\n";
str.flush();
#endif
}
void MyTreeCtrl::OnKeyDown(wxTreeEvent& WXUNUSED(event) )
{
if ( !wxGetApp().GetTopWindow() )
return;
wxTextCtrl *text = ((MyFrame *)wxGetApp().GetTopWindow())->m_logWindow;
if ( !text )
return;
#ifndef __GNUWIN32__
ostream str(text);
str << "OnKeyDown\n";
str.flush();
#endif
}

View File

@@ -319,14 +319,7 @@ wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
return NULL; return NULL;
} }
wxTreeItemData *data = (wxTreeItemData *)tvItem.lParam; return (wxTreeItemData *)tvItem.lParam;
if ( data != NULL )
{
// the data object should know about its id
data->m_itemId = item;
}
return data;
} }
void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
@@ -336,6 +329,13 @@ void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
DoSetItem(&tvItem); DoSetItem(&tvItem);
} }
void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
{
wxTreeViewItem tvItem(item, TVIF_CHILDREN);
tvItem.cChildren = (int)has;
DoSetItem(&tvItem);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Item status // Item status
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -466,6 +466,12 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent,
{ {
mask |= TVIF_IMAGE; mask |= TVIF_IMAGE;
tvIns.item.iImage = image; tvIns.item.iImage = image;
if ( selectedImage = -1 )
{
// take the same image for selected icon if not specified
selectedImage = image;
}
} }
if ( selectedImage != -1 ) if ( selectedImage != -1 )