1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: samples/treelist/treelist.cpp
3 // Purpose: Sample showing wxTreeListCtrl.
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
25 #if !wxUSE_TREELISTCTRL
26 #error "wxUSE_TREELISTCTRL must be 1 for this sample."
35 #include "wx/statusbr.h"
36 #include "wx/textctrl.h"
39 #include "wx/treelist.h"
41 #include "wx/aboutdlg.h"
42 #include "wx/artprov.h"
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 #if !defined(__WXMSW__) && !defined(__WXPM__)
49 #include "../sample.xpm"
52 // ----------------------------------------------------------------------------
53 // Constants for menu items
54 // ----------------------------------------------------------------------------
61 Id_NoCheckboxes
= Id_Checkboxes_Start
,
64 Id_CheckboxesUser3State
,
74 // ----------------------------------------------------------------------------
76 // ----------------------------------------------------------------------------
78 class MyApp
: public wxApp
81 virtual bool OnInit();
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 class MyFrame
: public wxFrame
95 // Event handlers for the menu and wxTreeListCtrl events.
96 void OnMultiSelect(wxCommandEvent
& event
);
97 void OnCheckboxes(wxCommandEvent
& event
);
98 void OnDumpSelection(wxCommandEvent
& event
);
99 void OnCheckHTMLDocs(wxCommandEvent
& event
);
100 void OnSelectHTMLDocs(wxCommandEvent
& event
);
102 void OnAbout(wxCommandEvent
& event
);
103 void OnExit(wxCommandEvent
& event
);
105 void OnSelectionChanged(wxTreeListEvent
& event
);
106 void OnItemExpanding(wxTreeListEvent
& event
);
107 void OnItemExpanded(wxTreeListEvent
& event
);
108 void OnItemChecked(wxTreeListEvent
& event
);
109 void OnItemActivated(wxTreeListEvent
& event
);
110 void OnItemContextMenu(wxTreeListEvent
& event
);
120 // Create the image list, called once only. Should add images to it in the
121 // same order as they appear in the enum above.
122 void InitImageList();
124 // Create the control with the given styles.
125 wxTreeListCtrl
* CreateTreeListCtrl(long style
);
127 // Recreate an already existing control.
128 void RecreateTreeListCtrl(long style
);
130 // Helper: return the text of the item or "NONE" if the item is invalid.
131 wxString
DumpItem(wxTreeListItem item
) const;
133 // Another helper: just translate wxCheckBoxState to user-readable text.
134 static const char* CheckedStateString(wxCheckBoxState state
);
137 wxImageList
* m_imageList
;
139 wxTreeListCtrl
* m_treelist
;
141 wxTreeListItem m_itemHTMLDocs
;
143 wxLog
* m_oldLogTarget
;
145 wxDECLARE_EVENT_TABLE();
148 // ============================================================================
150 // ============================================================================
152 // ----------------------------------------------------------------------------
154 // ----------------------------------------------------------------------------
156 wxIMPLEMENT_APP(MyApp
);
160 if ( !wxApp::OnInit() )
168 // ----------------------------------------------------------------------------
170 // ----------------------------------------------------------------------------
172 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
173 EVT_MENU(Id_MultiSelect
, MyFrame::OnMultiSelect
)
174 EVT_MENU_RANGE(Id_Checkboxes_Start
, Id_Checkboxes_End
,
175 MyFrame::OnCheckboxes
)
177 EVT_MENU(Id_DumpSelection
, MyFrame::OnDumpSelection
)
178 EVT_MENU_RANGE(Id_Check_HTMLDocs
, Id_Indet_HTMLDocs
,
179 MyFrame::OnCheckHTMLDocs
)
180 EVT_MENU(Id_Select_HTMLDocs
, MyFrame::OnSelectHTMLDocs
)
182 EVT_MENU(wxID_ABOUT
, MyFrame::OnAbout
)
183 EVT_MENU(wxID_EXIT
, MyFrame::OnExit
)
185 EVT_TREELIST_SELECTION_CHANGED(wxID_ANY
, MyFrame::OnSelectionChanged
)
186 EVT_TREELIST_ITEM_EXPANDING(wxID_ANY
, MyFrame::OnItemExpanding
)
187 EVT_TREELIST_ITEM_EXPANDED(wxID_ANY
, MyFrame::OnItemExpanded
)
188 EVT_TREELIST_ITEM_CHECKED(wxID_ANY
, MyFrame::OnItemChecked
)
189 EVT_TREELIST_ITEM_ACTIVATED(wxID_ANY
, MyFrame::OnItemActivated
)
190 EVT_TREELIST_ITEM_CONTEXT_MENU(wxID_ANY
, MyFrame::OnItemContextMenu
)
194 : wxFrame(NULL
, wxID_ANY
, "wxWidgets tree/list control sample",
195 wxDefaultPosition
, wxSize(600, 450))
197 // Create menus and status bar.
198 SetIcon(wxICON(sample
));
200 wxMenu
* fileMenu
= new wxMenu
;
201 fileMenu
->Append(wxID_EXIT
);
203 wxMenu
* treeStyle
= new wxMenu
;
204 treeStyle
->AppendCheckItem(Id_MultiSelect
, "&Multiple selections\tCtrl-M");
205 treeStyle
->AppendSeparator();
206 treeStyle
->AppendRadioItem(Id_NoCheckboxes
,
207 "&No checkboxes\tCtrl-1");
208 treeStyle
->AppendRadioItem(Id_Checkboxes2State
,
209 "&2-state checkboxes\tCtrl-2");
210 treeStyle
->AppendRadioItem(Id_Checkboxes3State
,
211 "&3-state checkboxes\tCtrl-3");
212 treeStyle
->AppendRadioItem(Id_CheckboxesUser3State
,
213 "&User-settable 3-state checkboxes\tCtrl-4");
215 wxMenu
* treeOper
= new wxMenu
;
216 treeOper
->Append(Id_DumpSelection
, "&Dump selection\tCtrl-D");
217 treeOper
->AppendSeparator();
218 treeOper
->Append(Id_Check_HTMLDocs
, "&Check Doc/HTML item\tCtrl-C");
219 treeOper
->Append(Id_Uncheck_HTMLDocs
, "&Uncheck Doc/HTML item\tCtrl-U");
220 treeOper
->Append(Id_Indet_HTMLDocs
, "Make Doc/HTML &indeterminate\tCtrl-I");
221 treeOper
->Append(Id_Select_HTMLDocs
, "&Select Doc/HTML item\tCtrl-S");
223 wxMenu
* helpMenu
= new wxMenu
;
224 helpMenu
->Append(wxID_ABOUT
);
226 wxMenuBar
* menuBar
= new wxMenuBar();
227 menuBar
->Append(fileMenu
, "&File");
228 menuBar
->Append(treeStyle
, "&Style");
229 menuBar
->Append(treeOper
, "&Operations");
230 menuBar
->Append(helpMenu
, "&Help");
236 // Construct the image list with the standard images.
240 // Create and layout child controls.
241 m_treelist
= CreateTreeListCtrl(wxTL_DEFAULT_STYLE
);
243 wxTextCtrl
* textLog
= new wxTextCtrl(this, wxID_ANY
, "",
244 wxDefaultPosition
, wxDefaultSize
,
245 wxTE_READONLY
| wxTE_MULTILINE
);
246 m_oldLogTarget
= wxLog::SetActiveTarget(new wxLogTextCtrl(textLog
));
248 wxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
249 sizer
->Add(m_treelist
, wxSizerFlags(2).Expand());
250 sizer
->Add(textLog
, wxSizerFlags(1).Expand());
254 // Finally show everything.
262 delete wxLog::SetActiveTarget(m_oldLogTarget
);
265 void MyFrame::InitImageList()
267 wxSize iconSize
= wxArtProvider::GetSizeHint(wxART_LIST
);
268 if ( iconSize
== wxDefaultSize
)
269 iconSize
= wxSize(16, 16);
271 m_imageList
= new wxImageList(iconSize
.x
, iconSize
.y
);
273 // The order should be the same as for the enum elements.
274 static const char* const icons
[] =
281 for ( unsigned n
= 0; n
< WXSIZEOF(icons
); n
++ )
285 wxArtProvider::GetIcon(icons
[n
], wxART_LIST
, iconSize
)
290 wxTreeListCtrl
* MyFrame::CreateTreeListCtrl(long style
)
292 wxTreeListCtrl
* const
293 tree
= new wxTreeListCtrl(this, wxID_ANY
,
294 wxDefaultPosition
, wxDefaultSize
,
296 tree
->SetImageList(m_imageList
);
305 tree
->AppendColumn("Component");
306 tree
->AppendColumn("# Files",
307 tree
->WidthFor("1,000,000"),
309 tree
->AppendColumn("Size",
310 tree
->WidthFor("1,000,000 KiB"),
313 // Define a shortcut to save on typing here.
314 #define ADD_ITEM(item, parent, files, size) \
315 wxTreeListItem item = tree->AppendItem(parent, #item, \
317 Icon_FolderOpened); \
318 tree->SetItemText(item, Col_Files, files); \
319 tree->SetItemText(item, Col_Size, size)
321 wxTreeListItem root
= tree
->GetRootItem();
322 ADD_ITEM(Code
, root
, "", "");
323 ADD_ITEM(wxMSW
, Code
, "313", "3.94 MiB");
324 ADD_ITEM(wxGTK
, Code
, "180", "1.66 MiB");
326 ADD_ITEM(wxOSX
, Code
, "265", "2.36 MiB");
327 ADD_ITEM(Core
, wxOSX
, "31", "347 KiB");
328 ADD_ITEM(Carbon
, wxOSX
, "91", "1.34 MiB");
329 ADD_ITEM(Cocoa
, wxOSX
, "46", "512 KiB");
331 ADD_ITEM(Documentation
, root
, "", "");
332 ADD_ITEM(HTML
, Documentation
, "many", "");
333 ADD_ITEM(CHM
, Documentation
, "1", "");
335 ADD_ITEM(Samples
, root
, "", "");
336 ADD_ITEM(minimal
, Samples
, "1", "7 KiB");
337 ADD_ITEM(widgets
, Samples
, "28", "419 KiB");
341 // Remember this one for subsequent tests.
342 m_itemHTMLDocs
= HTML
;
347 void MyFrame::RecreateTreeListCtrl(long style
)
349 wxTreeListCtrl
* const treelist
= CreateTreeListCtrl(style
);
350 GetSizer()->Replace(m_treelist
, treelist
);
353 m_treelist
= treelist
;
358 void MyFrame::OnMultiSelect(wxCommandEvent
& event
)
360 long style
= m_treelist
->GetWindowStyle();
362 if ( event
.IsChecked() )
363 style
|= wxTL_MULTIPLE
;
365 style
&= ~wxTL_MULTIPLE
;
367 RecreateTreeListCtrl(style
);
370 void MyFrame::OnCheckboxes(wxCommandEvent
& event
)
372 long style
= m_treelist
->GetWindowStyle();
373 style
&= ~(wxTL_CHECKBOX
| wxTL_3STATE
| wxTL_USER_3STATE
);
375 switch ( event
.GetId() )
377 case Id_NoCheckboxes
:
380 case Id_Checkboxes2State
:
381 style
|= wxTL_CHECKBOX
;
384 case Id_Checkboxes3State
:
385 style
|= wxTL_3STATE
;
388 case Id_CheckboxesUser3State
:
389 style
|= wxTL_USER_3STATE
;
393 wxFAIL_MSG( "Unknown checkbox style" );
397 RecreateTreeListCtrl(style
);
400 void MyFrame::OnDumpSelection(wxCommandEvent
& WXUNUSED(event
))
402 if ( m_treelist
->HasFlag(wxTL_MULTIPLE
) )
404 wxTreeListItems selections
;
405 const unsigned numSelected
= m_treelist
->GetSelections(selections
);
407 switch ( numSelected
)
410 wxLogMessage("No items selected");
414 wxLogMessage("Single item selected: %s",
415 DumpItem(selections
[0]));
419 wxLogMessage("%u items selected:", numSelected
);
420 for ( unsigned n
= 0; n
< numSelected
; n
++ )
422 wxLogMessage("\t%s", DumpItem(selections
[n
]));
426 else // Single selection
428 wxLogMessage("Selection: %s", DumpItem(m_treelist
->GetSelection()));
432 void MyFrame::OnCheckHTMLDocs(wxCommandEvent
& event
)
434 wxCheckBoxState state
;
436 switch ( event
.GetId() )
438 case Id_Uncheck_HTMLDocs
:
439 state
= wxCHK_UNCHECKED
;
442 case Id_Check_HTMLDocs
:
443 state
= wxCHK_CHECKED
;
446 case Id_Indet_HTMLDocs
:
447 state
= wxCHK_UNDETERMINED
;
451 wxFAIL_MSG( "Unknown check state" );
455 m_treelist
->CheckItem(m_itemHTMLDocs
, state
);
458 void MyFrame::OnSelectHTMLDocs(wxCommandEvent
& WXUNUSED(event
))
460 m_treelist
->Select(m_itemHTMLDocs
);
463 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
465 wxAboutDialogInfo info
;
466 info
.SetDescription("wxTreeListCtrl wxWidgets sample.");
467 info
.SetCopyright("(C) 2011 Vadim Zeitlin <vadim@wxwidgets.org>");
472 void MyFrame::OnExit(wxCommandEvent
& WXUNUSED(event
))
477 wxString
MyFrame::DumpItem(wxTreeListItem item
) const
479 return item
.IsOk() ? m_treelist
->GetItemText(item
) : wxString("NONE");
483 const char* MyFrame::CheckedStateString(wxCheckBoxState state
)
487 case wxCHK_UNCHECKED
:
490 case wxCHK_UNDETERMINED
:
491 return "undetermined";
500 void MyFrame::OnSelectionChanged(wxTreeListEvent
& event
)
504 if ( m_treelist
->HasFlag(wxTL_MULTIPLE
) )
505 msg
= "Selection of the \"%s\" item changed.";
507 msg
= "Selection changed, now is \"%s\".";
509 wxLogMessage(msg
, DumpItem(event
.GetItem()));
512 void MyFrame::OnItemExpanding(wxTreeListEvent
& event
)
514 wxLogMessage("Item \"%s\" is expanding", DumpItem(event
.GetItem()));
517 void MyFrame::OnItemExpanded(wxTreeListEvent
& event
)
519 wxLogMessage("Item \"%s\" expanded", DumpItem(event
.GetItem()));
522 void MyFrame::OnItemChecked(wxTreeListEvent
& event
)
524 wxTreeListItem item
= event
.GetItem();
526 wxLogMessage("Item \"%s\" toggled, now %s (was %s)",
528 CheckedStateString(m_treelist
->GetCheckedState(item
)),
529 CheckedStateString(event
.GetOldCheckedState()));
532 void MyFrame::OnItemActivated(wxTreeListEvent
& event
)
534 wxLogMessage("Item \"%s\" activated", DumpItem(event
.GetItem()));
537 void MyFrame::OnItemContextMenu(wxTreeListEvent
& event
)
544 Id_Check_Recursively
,
549 menu
.Append(Id_Check_Item
, "&Check item");
550 menu
.Append(Id_Uncheck_Item
, "&Uncheck item");
551 if ( m_treelist
->HasFlag(wxTL_3STATE
) )
552 menu
.Append(Id_Indet_Item
, "Make item &indeterminate");
553 menu
.AppendSeparator();
554 menu
.Append(Id_Check_Recursively
, "Check &recursively");
555 menu
.Append(Id_Update_Parent
, "Update &parent");
557 const wxTreeListItem item
= event
.GetItem();
558 switch ( m_treelist
->GetPopupMenuSelectionFromUser(menu
) )
561 m_treelist
->CheckItem(item
);
564 case Id_Uncheck_Item
:
565 m_treelist
->UncheckItem(item
);
569 m_treelist
->CheckItem(item
, wxCHK_UNDETERMINED
);
572 case Id_Check_Recursively
:
573 m_treelist
->CheckItemRecursively(item
);
576 case Id_Update_Parent
:
577 m_treelist
->UpdateItemParentStateRecursively(item
);
581 wxFAIL_MSG( "Unexpected menu selection" );