]> git.saurik.com Git - wxWidgets.git/blob - samples/treelist/treelist.cpp
No changes, just fix a typo in wxBannerWindow documentation.
[wxWidgets.git] / samples / treelist / treelist.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: samples/treelist/treelist.cpp
3 // Purpose: Sample showing wxTreeListCtrl.
4 // Author: Vadim Zeitlin
5 // Created: 2011-08-19
6 // RCS-ID: $Id$
7 // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // Declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // Headers
17 // ----------------------------------------------------------------------------
18
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #if !wxUSE_TREELISTCTRL
26 #error "wxUSE_TREELISTCTRL must be 1 for this sample."
27 #endif
28
29 #ifndef WX_PRECOMP
30 #include "wx/app.h"
31 #include "wx/frame.h"
32 #include "wx/log.h"
33 #include "wx/menu.h"
34 #include "wx/sizer.h"
35 #include "wx/statusbr.h"
36 #include "wx/textctrl.h"
37 #endif
38
39 #include "wx/treelist.h"
40
41 #include "wx/aboutdlg.h"
42 #include "wx/artprov.h"
43
44 // ----------------------------------------------------------------------------
45 // Resources
46 // ----------------------------------------------------------------------------
47
48 #if !defined(__WXMSW__) && !defined(__WXPM__)
49 #include "../sample.xpm"
50 #endif
51
52 // ----------------------------------------------------------------------------
53 // Constants for menu items
54 // ----------------------------------------------------------------------------
55
56 enum
57 {
58 Id_MultiSelect = 100,
59
60 Id_Checkboxes_Start,
61 Id_NoCheckboxes = Id_Checkboxes_Start,
62 Id_Checkboxes2State,
63 Id_Checkboxes3State,
64 Id_CheckboxesUser3State,
65 Id_Checkboxes_End,
66
67 Id_DumpSelection,
68 Id_Check_HTMLDocs,
69 Id_Uncheck_HTMLDocs,
70 Id_Indet_HTMLDocs,
71 Id_Select_HTMLDocs
72 };
73
74 // ----------------------------------------------------------------------------
75 // Application class
76 // ----------------------------------------------------------------------------
77
78 class MyApp : public wxApp
79 {
80 public:
81 virtual bool OnInit();
82 };
83
84 // ----------------------------------------------------------------------------
85 // Main window class
86 // ----------------------------------------------------------------------------
87
88 class MyFrame : public wxFrame
89 {
90 public:
91 MyFrame();
92 virtual ~MyFrame();
93
94 private:
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);
101
102 void OnAbout(wxCommandEvent& event);
103 void OnExit(wxCommandEvent& event);
104
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);
111
112
113 enum
114 {
115 Icon_File,
116 Icon_FolderClosed,
117 Icon_FolderOpened
118 };
119
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();
123
124 // Create the control with the given styles.
125 wxTreeListCtrl* CreateTreeListCtrl(long style);
126
127 // Recreate an already existing control.
128 void RecreateTreeListCtrl(long style);
129
130 // Helper: return the text of the item or "NONE" if the item is invalid.
131 wxString DumpItem(wxTreeListItem item) const;
132
133 // Another helper: just translate wxCheckBoxState to user-readable text.
134 static const char* CheckedStateString(wxCheckBoxState state);
135
136
137 wxImageList* m_imageList;
138
139 wxTreeListCtrl* m_treelist;
140
141 wxTreeListItem m_itemHTMLDocs;
142
143 wxLog* m_oldLogTarget;
144
145 wxDECLARE_EVENT_TABLE();
146 };
147
148 // ============================================================================
149 // Implementation
150 // ============================================================================
151
152 // ----------------------------------------------------------------------------
153 // Application class
154 // ----------------------------------------------------------------------------
155
156 wxIMPLEMENT_APP(MyApp);
157
158 bool MyApp::OnInit()
159 {
160 if ( !wxApp::OnInit() )
161 return false;
162
163 new MyFrame;
164
165 return true;
166 }
167
168 // ----------------------------------------------------------------------------
169 // Main window class
170 // ----------------------------------------------------------------------------
171
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)
176
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)
181
182 EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
183 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
184
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)
191 END_EVENT_TABLE()
192
193 MyFrame::MyFrame()
194 : wxFrame(NULL, wxID_ANY, "wxWidgets tree/list control sample",
195 wxDefaultPosition, wxSize(600, 450))
196 {
197 // Create menus and status bar.
198 SetIcon(wxICON(sample));
199
200 wxMenu* fileMenu = new wxMenu;
201 fileMenu->Append(wxID_EXIT);
202
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");
214
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");
222
223 wxMenu* helpMenu = new wxMenu;
224 helpMenu->Append(wxID_ABOUT);
225
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");
231 SetMenuBar(menuBar);
232
233 CreateStatusBar(1);
234
235
236 // Construct the image list with the standard images.
237 InitImageList();
238
239
240 // Create and layout child controls.
241 m_treelist = CreateTreeListCtrl(wxTL_DEFAULT_STYLE);
242
243 wxTextCtrl* textLog = new wxTextCtrl(this, wxID_ANY, "",
244 wxDefaultPosition, wxDefaultSize,
245 wxTE_READONLY | wxTE_MULTILINE);
246 m_oldLogTarget = wxLog::SetActiveTarget(new wxLogTextCtrl(textLog));
247
248 wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
249 sizer->Add(m_treelist, wxSizerFlags(2).Expand());
250 sizer->Add(textLog, wxSizerFlags(1).Expand());
251 SetSizer(sizer);
252
253
254 // Finally show everything.
255 Show();
256 }
257
258 MyFrame::~MyFrame()
259 {
260 delete m_imageList;
261
262 delete wxLog::SetActiveTarget(m_oldLogTarget);
263 }
264
265 void MyFrame::InitImageList()
266 {
267 wxSize iconSize = wxArtProvider::GetSizeHint(wxART_LIST);
268 if ( iconSize == wxDefaultSize )
269 iconSize = wxSize(16, 16);
270
271 m_imageList = new wxImageList(iconSize.x, iconSize.y);
272
273 // The order should be the same as for the enum elements.
274 static const char* const icons[] =
275 {
276 wxART_NORMAL_FILE,
277 wxART_FOLDER,
278 wxART_FOLDER_OPEN
279 };
280
281 for ( unsigned n = 0; n < WXSIZEOF(icons); n++ )
282 {
283 m_imageList->Add
284 (
285 wxArtProvider::GetIcon(icons[n], wxART_LIST, iconSize)
286 );
287 }
288 }
289
290 wxTreeListCtrl* MyFrame::CreateTreeListCtrl(long style)
291 {
292 wxTreeListCtrl* const
293 tree = new wxTreeListCtrl(this, wxID_ANY,
294 wxDefaultPosition, wxDefaultSize,
295 style);
296 tree->SetImageList(m_imageList);
297
298 enum
299 {
300 Col_Component,
301 Col_Files,
302 Col_Size
303 };
304
305 tree->AppendColumn("Component");
306 tree->AppendColumn("# Files",
307 tree->WidthFor("1,000,000"),
308 wxALIGN_RIGHT);
309 tree->AppendColumn("Size",
310 tree->WidthFor("1,000,000 KiB"),
311 wxALIGN_RIGHT);
312
313 // Define a shortcut to save on typing here.
314 #define ADD_ITEM(item, parent, files, size) \
315 wxTreeListItem item = tree->AppendItem(parent, #item, \
316 Icon_FolderClosed, \
317 Icon_FolderOpened); \
318 tree->SetItemText(item, Col_Files, files); \
319 tree->SetItemText(item, Col_Size, size)
320
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");
325
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");
330
331 ADD_ITEM(Documentation, root, "", "");
332 ADD_ITEM(HTML, Documentation, "many", "");
333 ADD_ITEM(CHM, Documentation, "1", "");
334
335 ADD_ITEM(Samples, root, "", "");
336 ADD_ITEM(minimal, Samples, "1", "7 KiB");
337 ADD_ITEM(widgets, Samples, "28", "419 KiB");
338
339 #undef ADD_ITEM
340
341 // Remember this one for subsequent tests.
342 m_itemHTMLDocs = HTML;
343
344 return tree;
345 }
346
347 void MyFrame::RecreateTreeListCtrl(long style)
348 {
349 wxTreeListCtrl* const treelist = CreateTreeListCtrl(style);
350 GetSizer()->Replace(m_treelist, treelist);
351
352 delete m_treelist;
353 m_treelist = treelist;
354
355 Layout();
356 }
357
358 void MyFrame::OnMultiSelect(wxCommandEvent& event)
359 {
360 long style = m_treelist->GetWindowStyle();
361
362 if ( event.IsChecked() )
363 style |= wxTL_MULTIPLE;
364 else
365 style &= ~wxTL_MULTIPLE;
366
367 RecreateTreeListCtrl(style);
368 }
369
370 void MyFrame::OnCheckboxes(wxCommandEvent& event)
371 {
372 long style = m_treelist->GetWindowStyle();
373 style &= ~(wxTL_CHECKBOX | wxTL_3STATE | wxTL_USER_3STATE);
374
375 switch ( event.GetId() )
376 {
377 case Id_NoCheckboxes:
378 break;
379
380 case Id_Checkboxes2State:
381 style |= wxTL_CHECKBOX;
382 break;
383
384 case Id_Checkboxes3State:
385 style |= wxTL_3STATE;
386 break;
387
388 case Id_CheckboxesUser3State:
389 style |= wxTL_USER_3STATE;
390 break;
391
392 default:
393 wxFAIL_MSG( "Unknown checkbox style" );
394 return;
395 }
396
397 RecreateTreeListCtrl(style);
398 }
399
400 void MyFrame::OnDumpSelection(wxCommandEvent& WXUNUSED(event))
401 {
402 if ( m_treelist->HasFlag(wxTL_MULTIPLE) )
403 {
404 wxTreeListItems selections;
405 const unsigned numSelected = m_treelist->GetSelections(selections);
406
407 switch ( numSelected )
408 {
409 case 0:
410 wxLogMessage("No items selected");
411 break;
412
413 case 1:
414 wxLogMessage("Single item selected: %s",
415 DumpItem(selections[0]));
416 break;
417
418 default:
419 wxLogMessage("%u items selected:", numSelected);
420 for ( unsigned n = 0; n < numSelected; n++ )
421 {
422 wxLogMessage("\t%s", DumpItem(selections[n]));
423 }
424 }
425 }
426 else // Single selection
427 {
428 wxLogMessage("Selection: %s", DumpItem(m_treelist->GetSelection()));
429 }
430 }
431
432 void MyFrame::OnCheckHTMLDocs(wxCommandEvent& event)
433 {
434 wxCheckBoxState state;
435
436 switch ( event.GetId() )
437 {
438 case Id_Uncheck_HTMLDocs:
439 state = wxCHK_UNCHECKED;
440 break;
441
442 case Id_Check_HTMLDocs:
443 state = wxCHK_CHECKED;
444 break;
445
446 case Id_Indet_HTMLDocs:
447 state = wxCHK_UNDETERMINED;
448 break;
449
450 default:
451 wxFAIL_MSG( "Unknown check state" );
452 return;
453 }
454
455 m_treelist->CheckItem(m_itemHTMLDocs, state);
456 }
457
458 void MyFrame::OnSelectHTMLDocs(wxCommandEvent& WXUNUSED(event))
459 {
460 m_treelist->Select(m_itemHTMLDocs);
461 }
462
463 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
464 {
465 wxAboutDialogInfo info;
466 info.SetDescription("wxTreeListCtrl wxWidgets sample.");
467 info.SetCopyright("(C) 2011 Vadim Zeitlin <vadim@wxwidgets.org>");
468
469 wxAboutBox(info);
470 }
471
472 void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
473 {
474 Close(true);
475 }
476
477 wxString MyFrame::DumpItem(wxTreeListItem item) const
478 {
479 return item.IsOk() ? m_treelist->GetItemText(item) : wxString("NONE");
480 }
481
482 /* static */
483 const char* MyFrame::CheckedStateString(wxCheckBoxState state)
484 {
485 switch ( state )
486 {
487 case wxCHK_UNCHECKED:
488 return "unchecked";
489
490 case wxCHK_UNDETERMINED:
491 return "undetermined";
492
493 case wxCHK_CHECKED:
494 return "checked";
495 }
496
497 return "invalid";
498 }
499
500 void MyFrame::OnSelectionChanged(wxTreeListEvent& event)
501 {
502 const char* msg;
503
504 if ( m_treelist->HasFlag(wxTL_MULTIPLE) )
505 msg = "Selection of the \"%s\" item changed.";
506 else
507 msg = "Selection changed, now is \"%s\".";
508
509 wxLogMessage(msg, DumpItem(event.GetItem()));
510 }
511
512 void MyFrame::OnItemExpanding(wxTreeListEvent& event)
513 {
514 wxLogMessage("Item \"%s\" is expanding", DumpItem(event.GetItem()));
515 }
516
517 void MyFrame::OnItemExpanded(wxTreeListEvent& event)
518 {
519 wxLogMessage("Item \"%s\" expanded", DumpItem(event.GetItem()));
520 }
521
522 void MyFrame::OnItemChecked(wxTreeListEvent& event)
523 {
524 wxTreeListItem item = event.GetItem();
525
526 wxLogMessage("Item \"%s\" toggled, now %s (was %s)",
527 DumpItem(item),
528 CheckedStateString(m_treelist->GetCheckedState(item)),
529 CheckedStateString(event.GetOldCheckedState()));
530 }
531
532 void MyFrame::OnItemActivated(wxTreeListEvent& event)
533 {
534 wxLogMessage("Item \"%s\" activated", DumpItem(event.GetItem()));
535 }
536
537 void MyFrame::OnItemContextMenu(wxTreeListEvent& event)
538 {
539 enum
540 {
541 Id_Check_Item,
542 Id_Uncheck_Item,
543 Id_Indet_Item,
544 Id_Check_Recursively,
545 Id_Update_Parent
546 };
547
548 wxMenu menu;
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");
556
557 const wxTreeListItem item = event.GetItem();
558 switch ( m_treelist->GetPopupMenuSelectionFromUser(menu) )
559 {
560 case Id_Check_Item:
561 m_treelist->CheckItem(item);
562 break;
563
564 case Id_Uncheck_Item:
565 m_treelist->UncheckItem(item);
566 break;
567
568 case Id_Indet_Item:
569 m_treelist->CheckItem(item, wxCHK_UNDETERMINED);
570 break;
571
572 case Id_Check_Recursively:
573 m_treelist->CheckItemRecursively(item);
574 break;
575
576 case Id_Update_Parent:
577 m_treelist->UpdateItemParentStateRecursively(item);
578 break;
579
580 default:
581 wxFAIL_MSG( "Unexpected menu selection" );
582 // Fall through.
583
584 case wxID_NONE:
585 return;
586 }
587 }