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 // ----------------------------------------------------------------------------
62 Id_NoCheckboxes
= Id_Checkboxes_Start
,
65 Id_CheckboxesUser3State
,
75 // ----------------------------------------------------------------------------
77 // ----------------------------------------------------------------------------
79 class MyApp
: public wxApp
82 virtual bool OnInit();
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 class MyFrame
: public wxFrame
96 // Event handlers for the menu and wxTreeListCtrl events.
97 void OnMultiSelect(wxCommandEvent
& event
);
98 void OnFlatList(wxCommandEvent
& event
);
99 void OnCheckboxes(wxCommandEvent
& event
);
100 void OnDumpSelection(wxCommandEvent
& event
);
101 void OnCheckHTMLDocs(wxCommandEvent
& event
);
102 void OnSelectHTMLDocs(wxCommandEvent
& event
);
104 void OnAbout(wxCommandEvent
& event
);
105 void OnExit(wxCommandEvent
& event
);
107 void OnSelectionChanged(wxTreeListEvent
& event
);
108 void OnItemExpanding(wxTreeListEvent
& event
);
109 void OnItemExpanded(wxTreeListEvent
& event
);
110 void OnItemChecked(wxTreeListEvent
& event
);
111 void OnItemActivated(wxTreeListEvent
& event
);
112 void OnItemContextMenu(wxTreeListEvent
& event
);
122 // Create the image list, called once only. Should add images to it in the
123 // same order as they appear in the enum above.
124 void InitImageList();
126 // Create the control with the given styles.
127 wxTreeListCtrl
* CreateTreeListCtrl(long style
);
129 // Recreate an already existing control.
130 void RecreateTreeListCtrl(long style
);
132 // Helper: return the text of the item or "NONE" if the item is invalid.
133 wxString
DumpItem(wxTreeListItem item
) const;
135 // Another helper: just translate wxCheckBoxState to user-readable text.
136 static const char* CheckedStateString(wxCheckBoxState state
);
139 wxImageList
* m_imageList
;
141 wxTreeListCtrl
* m_treelist
;
143 wxTreeListItem m_itemHTMLDocs
;
145 wxLog
* m_oldLogTarget
;
149 wxDECLARE_EVENT_TABLE();
152 // ============================================================================
154 // ============================================================================
156 // ----------------------------------------------------------------------------
158 // ----------------------------------------------------------------------------
160 wxIMPLEMENT_APP(MyApp
);
164 if ( !wxApp::OnInit() )
172 // ----------------------------------------------------------------------------
174 // ----------------------------------------------------------------------------
176 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
177 EVT_MENU(Id_MultiSelect
, MyFrame::OnMultiSelect
)
178 EVT_MENU(Id_FlatList
, MyFrame::OnFlatList
)
179 EVT_MENU_RANGE(Id_Checkboxes_Start
, Id_Checkboxes_End
,
180 MyFrame::OnCheckboxes
)
182 EVT_MENU(Id_DumpSelection
, MyFrame::OnDumpSelection
)
183 EVT_MENU_RANGE(Id_Check_HTMLDocs
, Id_Indet_HTMLDocs
,
184 MyFrame::OnCheckHTMLDocs
)
185 EVT_MENU(Id_Select_HTMLDocs
, MyFrame::OnSelectHTMLDocs
)
187 EVT_MENU(wxID_ABOUT
, MyFrame::OnAbout
)
188 EVT_MENU(wxID_EXIT
, MyFrame::OnExit
)
190 EVT_TREELIST_SELECTION_CHANGED(wxID_ANY
, MyFrame::OnSelectionChanged
)
191 EVT_TREELIST_ITEM_EXPANDING(wxID_ANY
, MyFrame::OnItemExpanding
)
192 EVT_TREELIST_ITEM_EXPANDED(wxID_ANY
, MyFrame::OnItemExpanded
)
193 EVT_TREELIST_ITEM_CHECKED(wxID_ANY
, MyFrame::OnItemChecked
)
194 EVT_TREELIST_ITEM_ACTIVATED(wxID_ANY
, MyFrame::OnItemActivated
)
195 EVT_TREELIST_ITEM_CONTEXT_MENU(wxID_ANY
, MyFrame::OnItemContextMenu
)
199 : wxFrame(NULL
, wxID_ANY
, "wxWidgets tree/list control sample",
200 wxDefaultPosition
, wxSize(600, 450))
204 // Create menus and status bar.
205 SetIcon(wxICON(sample
));
207 wxMenu
* fileMenu
= new wxMenu
;
208 fileMenu
->Append(wxID_EXIT
);
210 wxMenu
* treeStyle
= new wxMenu
;
211 treeStyle
->AppendCheckItem(Id_MultiSelect
, "&Multiple selections\tCtrl-M");
212 treeStyle
->AppendSeparator();
213 treeStyle
->AppendRadioItem(Id_NoCheckboxes
,
214 "&No checkboxes\tCtrl-1");
215 treeStyle
->AppendRadioItem(Id_Checkboxes2State
,
216 "&2-state checkboxes\tCtrl-2");
217 treeStyle
->AppendRadioItem(Id_Checkboxes3State
,
218 "&3-state checkboxes\tCtrl-3");
219 treeStyle
->AppendRadioItem(Id_CheckboxesUser3State
,
220 "&User-settable 3-state checkboxes\tCtrl-4");
221 treeStyle
->AppendSeparator();
222 treeStyle
->AppendCheckItem(Id_FlatList
, "&Flat list");
224 wxMenu
* treeOper
= new wxMenu
;
225 treeOper
->Append(Id_DumpSelection
, "&Dump selection\tCtrl-D");
226 treeOper
->AppendSeparator();
227 treeOper
->Append(Id_Check_HTMLDocs
, "&Check Doc/HTML item\tCtrl-C");
228 treeOper
->Append(Id_Uncheck_HTMLDocs
, "&Uncheck Doc/HTML item\tCtrl-U");
229 treeOper
->Append(Id_Indet_HTMLDocs
, "Make Doc/HTML &indeterminate\tCtrl-I");
230 treeOper
->Append(Id_Select_HTMLDocs
, "&Select Doc/HTML item\tCtrl-S");
232 wxMenu
* helpMenu
= new wxMenu
;
233 helpMenu
->Append(wxID_ABOUT
);
235 wxMenuBar
* menuBar
= new wxMenuBar();
236 menuBar
->Append(fileMenu
, "&File");
237 menuBar
->Append(treeStyle
, "&Style");
238 menuBar
->Append(treeOper
, "&Operations");
239 menuBar
->Append(helpMenu
, "&Help");
245 // Construct the image list with the standard images.
249 // Create and layout child controls.
250 m_treelist
= CreateTreeListCtrl(wxTL_DEFAULT_STYLE
);
252 wxTextCtrl
* textLog
= new wxTextCtrl(this, wxID_ANY
, "",
253 wxDefaultPosition
, wxDefaultSize
,
254 wxTE_READONLY
| wxTE_MULTILINE
);
255 m_oldLogTarget
= wxLog::SetActiveTarget(new wxLogTextCtrl(textLog
));
257 wxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
258 sizer
->Add(m_treelist
, wxSizerFlags(2).Expand());
259 sizer
->Add(textLog
, wxSizerFlags(1).Expand());
263 // Finally show everything.
271 delete wxLog::SetActiveTarget(m_oldLogTarget
);
274 void MyFrame::InitImageList()
276 wxSize iconSize
= wxArtProvider::GetSizeHint(wxART_LIST
);
277 if ( iconSize
== wxDefaultSize
)
278 iconSize
= wxSize(16, 16);
280 m_imageList
= new wxImageList(iconSize
.x
, iconSize
.y
);
282 // The order should be the same as for the enum elements.
283 static const char* const icons
[] =
290 for ( unsigned n
= 0; n
< WXSIZEOF(icons
); n
++ )
294 wxArtProvider::GetIcon(icons
[n
], wxART_LIST
, iconSize
)
299 wxTreeListCtrl
* MyFrame::CreateTreeListCtrl(long style
)
301 wxTreeListCtrl
* const
302 tree
= new wxTreeListCtrl(this, wxID_ANY
,
303 wxDefaultPosition
, wxDefaultSize
,
305 tree
->SetImageList(m_imageList
);
314 tree
->AppendColumn("Component");
315 tree
->AppendColumn("# Files",
316 tree
->WidthFor("1,000,000"),
318 tree
->AppendColumn("Size",
319 tree
->WidthFor("1,000,000 KiB"),
322 // Define a shortcut to save on typing here.
323 #define ADD_ITEM(item, parent, files, size) \
324 wxTreeListItem item = tree->AppendItem(m_isFlat ? root : parent, \
327 Icon_FolderOpened); \
328 tree->SetItemText(item, Col_Files, files); \
329 tree->SetItemText(item, Col_Size, size)
331 wxTreeListItem root
= tree
->GetRootItem();
332 ADD_ITEM(Code
, root
, "", "");
333 ADD_ITEM(wxMSW
, Code
, "313", "3.94 MiB");
334 ADD_ITEM(wxGTK
, Code
, "180", "1.66 MiB");
336 ADD_ITEM(wxOSX
, Code
, "265", "2.36 MiB");
337 ADD_ITEM(Core
, wxOSX
, "31", "347 KiB");
338 ADD_ITEM(Carbon
, wxOSX
, "91", "1.34 MiB");
339 ADD_ITEM(Cocoa
, wxOSX
, "46", "512 KiB");
341 ADD_ITEM(Documentation
, root
, "", "");
342 ADD_ITEM(HTML
, Documentation
, "many", "");
343 ADD_ITEM(CHM
, Documentation
, "1", "");
345 ADD_ITEM(Samples
, root
, "", "");
346 ADD_ITEM(minimal
, Samples
, "1", "7 KiB");
347 ADD_ITEM(widgets
, Samples
, "28", "419 KiB");
351 // Remember this one for subsequent tests.
352 m_itemHTMLDocs
= HTML
;
357 void MyFrame::RecreateTreeListCtrl(long style
)
359 wxTreeListCtrl
* const treelist
= CreateTreeListCtrl(style
);
360 GetSizer()->Replace(m_treelist
, treelist
);
363 m_treelist
= treelist
;
368 void MyFrame::OnMultiSelect(wxCommandEvent
& event
)
370 long style
= m_treelist
->GetWindowStyle();
372 if ( event
.IsChecked() )
373 style
|= wxTL_MULTIPLE
;
375 style
&= ~wxTL_MULTIPLE
;
377 RecreateTreeListCtrl(style
);
380 void MyFrame::OnFlatList(wxCommandEvent
& event
)
382 m_isFlat
= event
.IsChecked();
384 RecreateTreeListCtrl(m_treelist
->GetWindowStyle());
387 void MyFrame::OnCheckboxes(wxCommandEvent
& event
)
389 long style
= m_treelist
->GetWindowStyle();
390 style
&= ~(wxTL_CHECKBOX
| wxTL_3STATE
| wxTL_USER_3STATE
);
392 switch ( event
.GetId() )
394 case Id_NoCheckboxes
:
397 case Id_Checkboxes2State
:
398 style
|= wxTL_CHECKBOX
;
401 case Id_Checkboxes3State
:
402 style
|= wxTL_3STATE
;
405 case Id_CheckboxesUser3State
:
406 style
|= wxTL_USER_3STATE
;
410 wxFAIL_MSG( "Unknown checkbox style" );
414 RecreateTreeListCtrl(style
);
417 void MyFrame::OnDumpSelection(wxCommandEvent
& WXUNUSED(event
))
419 if ( m_treelist
->HasFlag(wxTL_MULTIPLE
) )
421 wxTreeListItems selections
;
422 const unsigned numSelected
= m_treelist
->GetSelections(selections
);
424 switch ( numSelected
)
427 wxLogMessage("No items selected");
431 wxLogMessage("Single item selected: %s",
432 DumpItem(selections
[0]));
436 wxLogMessage("%u items selected:", numSelected
);
437 for ( unsigned n
= 0; n
< numSelected
; n
++ )
439 wxLogMessage("\t%s", DumpItem(selections
[n
]));
443 else // Single selection
445 wxLogMessage("Selection: %s", DumpItem(m_treelist
->GetSelection()));
449 void MyFrame::OnCheckHTMLDocs(wxCommandEvent
& event
)
451 wxCheckBoxState state
;
453 switch ( event
.GetId() )
455 case Id_Uncheck_HTMLDocs
:
456 state
= wxCHK_UNCHECKED
;
459 case Id_Check_HTMLDocs
:
460 state
= wxCHK_CHECKED
;
463 case Id_Indet_HTMLDocs
:
464 state
= wxCHK_UNDETERMINED
;
468 wxFAIL_MSG( "Unknown check state" );
472 m_treelist
->CheckItem(m_itemHTMLDocs
, state
);
475 void MyFrame::OnSelectHTMLDocs(wxCommandEvent
& WXUNUSED(event
))
477 m_treelist
->Select(m_itemHTMLDocs
);
480 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
482 wxAboutDialogInfo info
;
483 info
.SetDescription("wxTreeListCtrl wxWidgets sample.");
484 info
.SetCopyright("(C) 2011 Vadim Zeitlin <vadim@wxwidgets.org>");
489 void MyFrame::OnExit(wxCommandEvent
& WXUNUSED(event
))
494 wxString
MyFrame::DumpItem(wxTreeListItem item
) const
496 return item
.IsOk() ? m_treelist
->GetItemText(item
) : wxString("NONE");
500 const char* MyFrame::CheckedStateString(wxCheckBoxState state
)
504 case wxCHK_UNCHECKED
:
507 case wxCHK_UNDETERMINED
:
508 return "undetermined";
517 void MyFrame::OnSelectionChanged(wxTreeListEvent
& event
)
521 if ( m_treelist
->HasFlag(wxTL_MULTIPLE
) )
522 msg
= "Selection of the \"%s\" item changed.";
524 msg
= "Selection changed, now is \"%s\".";
526 wxLogMessage(msg
, DumpItem(event
.GetItem()));
529 void MyFrame::OnItemExpanding(wxTreeListEvent
& event
)
531 wxLogMessage("Item \"%s\" is expanding", DumpItem(event
.GetItem()));
534 void MyFrame::OnItemExpanded(wxTreeListEvent
& event
)
536 wxLogMessage("Item \"%s\" expanded", DumpItem(event
.GetItem()));
539 void MyFrame::OnItemChecked(wxTreeListEvent
& event
)
541 wxTreeListItem item
= event
.GetItem();
543 wxLogMessage("Item \"%s\" toggled, now %s (was %s)",
545 CheckedStateString(m_treelist
->GetCheckedState(item
)),
546 CheckedStateString(event
.GetOldCheckedState()));
549 void MyFrame::OnItemActivated(wxTreeListEvent
& event
)
551 wxLogMessage("Item \"%s\" activated", DumpItem(event
.GetItem()));
554 void MyFrame::OnItemContextMenu(wxTreeListEvent
& event
)
561 Id_Check_Recursively
,
566 menu
.Append(Id_Check_Item
, "&Check item");
567 menu
.Append(Id_Uncheck_Item
, "&Uncheck item");
568 if ( m_treelist
->HasFlag(wxTL_3STATE
) )
569 menu
.Append(Id_Indet_Item
, "Make item &indeterminate");
570 menu
.AppendSeparator();
571 menu
.Append(Id_Check_Recursively
, "Check &recursively");
572 menu
.Append(Id_Update_Parent
, "Update &parent");
574 const wxTreeListItem item
= event
.GetItem();
575 switch ( m_treelist
->GetPopupMenuSelectionFromUser(menu
) )
578 m_treelist
->CheckItem(item
);
581 case Id_Uncheck_Item
:
582 m_treelist
->UncheckItem(item
);
586 m_treelist
->CheckItem(item
, wxCHK_UNDETERMINED
);
589 case Id_Check_Recursively
:
590 m_treelist
->CheckItemRecursively(item
);
593 case Id_Update_Parent
:
594 m_treelist
->UpdateItemParentStateRecursively(item
);
598 wxFAIL_MSG( "Unexpected menu selection" );