]> git.saurik.com Git - wxWidgets.git/blob - samples/treelist/treelist.cpp
Correctly disable webkit backend if the appropriate headers cannot be found.
[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 Id_FlatList,
60
61 Id_Checkboxes_Start,
62 Id_NoCheckboxes = Id_Checkboxes_Start,
63 Id_Checkboxes2State,
64 Id_Checkboxes3State,
65 Id_CheckboxesUser3State,
66 Id_Checkboxes_End,
67
68 Id_DumpSelection,
69 Id_Check_HTMLDocs,
70 Id_Uncheck_HTMLDocs,
71 Id_Indet_HTMLDocs,
72 Id_Select_HTMLDocs
73 };
74
75 // ----------------------------------------------------------------------------
76 // Application class
77 // ----------------------------------------------------------------------------
78
79 class MyApp : public wxApp
80 {
81 public:
82 virtual bool OnInit();
83 };
84
85 // ----------------------------------------------------------------------------
86 // Main window class
87 // ----------------------------------------------------------------------------
88
89 class MyFrame : public wxFrame
90 {
91 public:
92 MyFrame();
93 virtual ~MyFrame();
94
95 private:
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);
103
104 void OnAbout(wxCommandEvent& event);
105 void OnExit(wxCommandEvent& event);
106
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);
113
114
115 enum
116 {
117 Icon_File,
118 Icon_FolderClosed,
119 Icon_FolderOpened
120 };
121
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();
125
126 // Create the control with the given styles.
127 wxTreeListCtrl* CreateTreeListCtrl(long style);
128
129 // Recreate an already existing control.
130 void RecreateTreeListCtrl(long style);
131
132 // Helper: return the text of the item or "NONE" if the item is invalid.
133 wxString DumpItem(wxTreeListItem item) const;
134
135 // Another helper: just translate wxCheckBoxState to user-readable text.
136 static const char* CheckedStateString(wxCheckBoxState state);
137
138
139 wxImageList* m_imageList;
140
141 wxTreeListCtrl* m_treelist;
142
143 wxTreeListItem m_itemHTMLDocs;
144
145 wxLog* m_oldLogTarget;
146
147 bool m_isFlat;
148
149 wxDECLARE_EVENT_TABLE();
150 };
151
152 // ============================================================================
153 // Implementation
154 // ============================================================================
155
156 // ----------------------------------------------------------------------------
157 // Application class
158 // ----------------------------------------------------------------------------
159
160 wxIMPLEMENT_APP(MyApp);
161
162 bool MyApp::OnInit()
163 {
164 if ( !wxApp::OnInit() )
165 return false;
166
167 new MyFrame;
168
169 return true;
170 }
171
172 // ----------------------------------------------------------------------------
173 // Main window class
174 // ----------------------------------------------------------------------------
175
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)
181
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)
186
187 EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
188 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
189
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)
196 END_EVENT_TABLE()
197
198 MyFrame::MyFrame()
199 : wxFrame(NULL, wxID_ANY, "wxWidgets tree/list control sample",
200 wxDefaultPosition, wxSize(600, 450))
201 {
202 m_isFlat = false;
203
204 // Create menus and status bar.
205 SetIcon(wxICON(sample));
206
207 wxMenu* fileMenu = new wxMenu;
208 fileMenu->Append(wxID_EXIT);
209
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");
223
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");
231
232 wxMenu* helpMenu = new wxMenu;
233 helpMenu->Append(wxID_ABOUT);
234
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");
240 SetMenuBar(menuBar);
241
242 CreateStatusBar(1);
243
244
245 // Construct the image list with the standard images.
246 InitImageList();
247
248
249 // Create and layout child controls.
250 m_treelist = CreateTreeListCtrl(wxTL_DEFAULT_STYLE);
251
252 wxTextCtrl* textLog = new wxTextCtrl(this, wxID_ANY, "",
253 wxDefaultPosition, wxDefaultSize,
254 wxTE_READONLY | wxTE_MULTILINE);
255 m_oldLogTarget = wxLog::SetActiveTarget(new wxLogTextCtrl(textLog));
256
257 wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
258 sizer->Add(m_treelist, wxSizerFlags(2).Expand());
259 sizer->Add(textLog, wxSizerFlags(1).Expand());
260 SetSizer(sizer);
261
262
263 // Finally show everything.
264 Show();
265 }
266
267 MyFrame::~MyFrame()
268 {
269 delete m_imageList;
270
271 delete wxLog::SetActiveTarget(m_oldLogTarget);
272 }
273
274 void MyFrame::InitImageList()
275 {
276 wxSize iconSize = wxArtProvider::GetSizeHint(wxART_LIST);
277 if ( iconSize == wxDefaultSize )
278 iconSize = wxSize(16, 16);
279
280 m_imageList = new wxImageList(iconSize.x, iconSize.y);
281
282 // The order should be the same as for the enum elements.
283 static const char* const icons[] =
284 {
285 wxART_NORMAL_FILE,
286 wxART_FOLDER,
287 wxART_FOLDER_OPEN
288 };
289
290 for ( unsigned n = 0; n < WXSIZEOF(icons); n++ )
291 {
292 m_imageList->Add
293 (
294 wxArtProvider::GetIcon(icons[n], wxART_LIST, iconSize)
295 );
296 }
297 }
298
299 wxTreeListCtrl* MyFrame::CreateTreeListCtrl(long style)
300 {
301 wxTreeListCtrl* const
302 tree = new wxTreeListCtrl(this, wxID_ANY,
303 wxDefaultPosition, wxDefaultSize,
304 style);
305 tree->SetImageList(m_imageList);
306
307 enum
308 {
309 Col_Component,
310 Col_Files,
311 Col_Size
312 };
313
314 tree->AppendColumn("Component");
315 tree->AppendColumn("# Files",
316 tree->WidthFor("1,000,000"),
317 wxALIGN_RIGHT);
318 tree->AppendColumn("Size",
319 tree->WidthFor("1,000,000 KiB"),
320 wxALIGN_RIGHT);
321
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, \
325 #item, \
326 Icon_FolderClosed, \
327 Icon_FolderOpened); \
328 tree->SetItemText(item, Col_Files, files); \
329 tree->SetItemText(item, Col_Size, size)
330
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");
335
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");
340
341 ADD_ITEM(Documentation, root, "", "");
342 ADD_ITEM(HTML, Documentation, "many", "");
343 ADD_ITEM(CHM, Documentation, "1", "");
344
345 ADD_ITEM(Samples, root, "", "");
346 ADD_ITEM(minimal, Samples, "1", "7 KiB");
347 ADD_ITEM(widgets, Samples, "28", "419 KiB");
348
349 #undef ADD_ITEM
350
351 // Remember this one for subsequent tests.
352 m_itemHTMLDocs = HTML;
353
354 return tree;
355 }
356
357 void MyFrame::RecreateTreeListCtrl(long style)
358 {
359 wxTreeListCtrl* const treelist = CreateTreeListCtrl(style);
360 GetSizer()->Replace(m_treelist, treelist);
361
362 delete m_treelist;
363 m_treelist = treelist;
364
365 Layout();
366 }
367
368 void MyFrame::OnMultiSelect(wxCommandEvent& event)
369 {
370 long style = m_treelist->GetWindowStyle();
371
372 if ( event.IsChecked() )
373 style |= wxTL_MULTIPLE;
374 else
375 style &= ~wxTL_MULTIPLE;
376
377 RecreateTreeListCtrl(style);
378 }
379
380 void MyFrame::OnFlatList(wxCommandEvent& event)
381 {
382 m_isFlat = event.IsChecked();
383
384 RecreateTreeListCtrl(m_treelist->GetWindowStyle());
385 }
386
387 void MyFrame::OnCheckboxes(wxCommandEvent& event)
388 {
389 long style = m_treelist->GetWindowStyle();
390 style &= ~(wxTL_CHECKBOX | wxTL_3STATE | wxTL_USER_3STATE);
391
392 switch ( event.GetId() )
393 {
394 case Id_NoCheckboxes:
395 break;
396
397 case Id_Checkboxes2State:
398 style |= wxTL_CHECKBOX;
399 break;
400
401 case Id_Checkboxes3State:
402 style |= wxTL_3STATE;
403 break;
404
405 case Id_CheckboxesUser3State:
406 style |= wxTL_USER_3STATE;
407 break;
408
409 default:
410 wxFAIL_MSG( "Unknown checkbox style" );
411 return;
412 }
413
414 RecreateTreeListCtrl(style);
415 }
416
417 void MyFrame::OnDumpSelection(wxCommandEvent& WXUNUSED(event))
418 {
419 if ( m_treelist->HasFlag(wxTL_MULTIPLE) )
420 {
421 wxTreeListItems selections;
422 const unsigned numSelected = m_treelist->GetSelections(selections);
423
424 switch ( numSelected )
425 {
426 case 0:
427 wxLogMessage("No items selected");
428 break;
429
430 case 1:
431 wxLogMessage("Single item selected: %s",
432 DumpItem(selections[0]));
433 break;
434
435 default:
436 wxLogMessage("%u items selected:", numSelected);
437 for ( unsigned n = 0; n < numSelected; n++ )
438 {
439 wxLogMessage("\t%s", DumpItem(selections[n]));
440 }
441 }
442 }
443 else // Single selection
444 {
445 wxLogMessage("Selection: %s", DumpItem(m_treelist->GetSelection()));
446 }
447 }
448
449 void MyFrame::OnCheckHTMLDocs(wxCommandEvent& event)
450 {
451 wxCheckBoxState state;
452
453 switch ( event.GetId() )
454 {
455 case Id_Uncheck_HTMLDocs:
456 state = wxCHK_UNCHECKED;
457 break;
458
459 case Id_Check_HTMLDocs:
460 state = wxCHK_CHECKED;
461 break;
462
463 case Id_Indet_HTMLDocs:
464 state = wxCHK_UNDETERMINED;
465 break;
466
467 default:
468 wxFAIL_MSG( "Unknown check state" );
469 return;
470 }
471
472 m_treelist->CheckItem(m_itemHTMLDocs, state);
473 }
474
475 void MyFrame::OnSelectHTMLDocs(wxCommandEvent& WXUNUSED(event))
476 {
477 m_treelist->Select(m_itemHTMLDocs);
478 }
479
480 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
481 {
482 wxAboutDialogInfo info;
483 info.SetDescription("wxTreeListCtrl wxWidgets sample.");
484 info.SetCopyright("(C) 2011 Vadim Zeitlin <vadim@wxwidgets.org>");
485
486 wxAboutBox(info);
487 }
488
489 void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
490 {
491 Close(true);
492 }
493
494 wxString MyFrame::DumpItem(wxTreeListItem item) const
495 {
496 return item.IsOk() ? m_treelist->GetItemText(item) : wxString("NONE");
497 }
498
499 /* static */
500 const char* MyFrame::CheckedStateString(wxCheckBoxState state)
501 {
502 switch ( state )
503 {
504 case wxCHK_UNCHECKED:
505 return "unchecked";
506
507 case wxCHK_UNDETERMINED:
508 return "undetermined";
509
510 case wxCHK_CHECKED:
511 return "checked";
512 }
513
514 return "invalid";
515 }
516
517 void MyFrame::OnSelectionChanged(wxTreeListEvent& event)
518 {
519 const char* msg;
520
521 if ( m_treelist->HasFlag(wxTL_MULTIPLE) )
522 msg = "Selection of the \"%s\" item changed.";
523 else
524 msg = "Selection changed, now is \"%s\".";
525
526 wxLogMessage(msg, DumpItem(event.GetItem()));
527 }
528
529 void MyFrame::OnItemExpanding(wxTreeListEvent& event)
530 {
531 wxLogMessage("Item \"%s\" is expanding", DumpItem(event.GetItem()));
532 }
533
534 void MyFrame::OnItemExpanded(wxTreeListEvent& event)
535 {
536 wxLogMessage("Item \"%s\" expanded", DumpItem(event.GetItem()));
537 }
538
539 void MyFrame::OnItemChecked(wxTreeListEvent& event)
540 {
541 wxTreeListItem item = event.GetItem();
542
543 wxLogMessage("Item \"%s\" toggled, now %s (was %s)",
544 DumpItem(item),
545 CheckedStateString(m_treelist->GetCheckedState(item)),
546 CheckedStateString(event.GetOldCheckedState()));
547 }
548
549 void MyFrame::OnItemActivated(wxTreeListEvent& event)
550 {
551 wxLogMessage("Item \"%s\" activated", DumpItem(event.GetItem()));
552 }
553
554 void MyFrame::OnItemContextMenu(wxTreeListEvent& event)
555 {
556 enum
557 {
558 Id_Check_Item,
559 Id_Uncheck_Item,
560 Id_Indet_Item,
561 Id_Check_Recursively,
562 Id_Update_Parent
563 };
564
565 wxMenu menu;
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");
573
574 const wxTreeListItem item = event.GetItem();
575 switch ( m_treelist->GetPopupMenuSelectionFromUser(menu) )
576 {
577 case Id_Check_Item:
578 m_treelist->CheckItem(item);
579 break;
580
581 case Id_Uncheck_Item:
582 m_treelist->UncheckItem(item);
583 break;
584
585 case Id_Indet_Item:
586 m_treelist->CheckItem(item, wxCHK_UNDETERMINED);
587 break;
588
589 case Id_Check_Recursively:
590 m_treelist->CheckItemRecursively(item);
591 break;
592
593 case Id_Update_Parent:
594 m_treelist->UpdateItemParentStateRecursively(item);
595 break;
596
597 default:
598 wxFAIL_MSG( "Unexpected menu selection" );
599 // Fall through.
600
601 case wxID_NONE:
602 return;
603 }
604 }