]>
Commit | Line | Data |
---|---|---|
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 | #ifndef wxHAS_IMAGES_IN_RESOURCES | |
49 | #include "../sample.xpm" | |
50 | #endif | |
51 | ||
52 | // ---------------------------------------------------------------------------- | |
53 | // Constants | |
54 | // ---------------------------------------------------------------------------- | |
55 | ||
56 | // Menu items. | |
57 | enum | |
58 | { | |
59 | Id_MultiSelect = 100, | |
60 | Id_FlatList, | |
61 | ||
62 | Id_Checkboxes_Start, | |
63 | Id_NoCheckboxes = Id_Checkboxes_Start, | |
64 | Id_Checkboxes2State, | |
65 | Id_Checkboxes3State, | |
66 | Id_CheckboxesUser3State, | |
67 | Id_Checkboxes_End, | |
68 | ||
69 | Id_DumpSelection, | |
70 | Id_Check_HTMLDocs, | |
71 | Id_Uncheck_HTMLDocs, | |
72 | Id_Indet_HTMLDocs, | |
73 | Id_Select_HTMLDocs | |
74 | }; | |
75 | ||
76 | // Tree list columns. | |
77 | enum | |
78 | { | |
79 | Col_Component, | |
80 | Col_Files, | |
81 | Col_Size | |
82 | }; | |
83 | ||
84 | // ---------------------------------------------------------------------------- | |
85 | // Custom comparator for tree list items comparison | |
86 | // ---------------------------------------------------------------------------- | |
87 | ||
88 | // This is a toy class as in a real program you would have the original numeric | |
89 | // data somewhere and wouldn't need to parse it back from strings presumably. | |
90 | // Nevertheless it shows how to implement a custom comparator which is needed | |
91 | // if you want to sort by a column with non-textual contents. | |
92 | class MyComparator : public wxTreeListItemComparator | |
93 | { | |
94 | public: | |
95 | virtual int | |
96 | Compare(wxTreeListCtrl* treelist, | |
97 | unsigned column, | |
98 | wxTreeListItem item1, | |
99 | wxTreeListItem item2) | |
100 | { | |
101 | wxString text1 = treelist->GetItemText(item1, column), | |
102 | text2 = treelist->GetItemText(item2, column); | |
103 | ||
104 | switch ( column ) | |
105 | { | |
106 | case Col_Component: | |
107 | // Simple alphabetical comparison is fine for those. | |
108 | return text1.CmpNoCase(text2); | |
109 | ||
110 | case Col_Files: | |
111 | // Compare strings as numbers. | |
112 | return GetNumFilesFromText(text1) - GetNumFilesFromText(text2); | |
113 | ||
114 | case Col_Size: | |
115 | // Compare strings as numbers but also take care of "KiB" and | |
116 | // "MiB" suffixes. | |
117 | return GetSizeFromText(text1) - GetSizeFromText(text2); | |
118 | } | |
119 | ||
120 | wxFAIL_MSG( "Sorting on unknown column?" ); | |
121 | ||
122 | return 0; | |
123 | } | |
124 | ||
125 | private: | |
126 | // Return the number of files handling special value "many". Notice that | |
127 | // the returned value is signed to allow using it in subtraction above. | |
128 | int GetNumFilesFromText(const wxString& text) const | |
129 | { | |
130 | unsigned long n; | |
131 | if ( !text.ToULong(&n) ) | |
132 | { | |
133 | if ( text == "many" ) | |
134 | n = 9999; | |
135 | else | |
136 | n = 0; | |
137 | } | |
138 | ||
139 | return n; | |
140 | } | |
141 | ||
142 | // Return the size in KiB from a string with either KiB or MiB suffix. | |
143 | int GetSizeFromText(const wxString& text) const | |
144 | { | |
145 | wxString size; | |
146 | unsigned factor = 1; | |
147 | if ( text.EndsWith(" MiB", &size) ) | |
148 | factor = 1024; | |
149 | else if ( !text.EndsWith(" KiB", &size) ) | |
150 | return 0; | |
151 | ||
152 | unsigned long n = 0; | |
153 | size.ToULong(&n); | |
154 | ||
155 | return n*factor; | |
156 | } | |
157 | }; | |
158 | ||
159 | // ---------------------------------------------------------------------------- | |
160 | // Application class | |
161 | // ---------------------------------------------------------------------------- | |
162 | ||
163 | class MyApp : public wxApp | |
164 | { | |
165 | public: | |
166 | virtual bool OnInit(); | |
167 | }; | |
168 | ||
169 | // ---------------------------------------------------------------------------- | |
170 | // Main window class | |
171 | // ---------------------------------------------------------------------------- | |
172 | ||
173 | class MyFrame : public wxFrame | |
174 | { | |
175 | public: | |
176 | MyFrame(); | |
177 | virtual ~MyFrame(); | |
178 | ||
179 | private: | |
180 | // Event handlers for the menu and wxTreeListCtrl events. | |
181 | void OnMultiSelect(wxCommandEvent& event); | |
182 | void OnFlatList(wxCommandEvent& event); | |
183 | void OnCheckboxes(wxCommandEvent& event); | |
184 | void OnDumpSelection(wxCommandEvent& event); | |
185 | void OnCheckHTMLDocs(wxCommandEvent& event); | |
186 | void OnSelectHTMLDocs(wxCommandEvent& event); | |
187 | ||
188 | void OnAbout(wxCommandEvent& event); | |
189 | void OnExit(wxCommandEvent& event); | |
190 | ||
191 | void OnSelectionChanged(wxTreeListEvent& event); | |
192 | void OnItemExpanding(wxTreeListEvent& event); | |
193 | void OnItemExpanded(wxTreeListEvent& event); | |
194 | void OnItemChecked(wxTreeListEvent& event); | |
195 | void OnItemActivated(wxTreeListEvent& event); | |
196 | void OnItemContextMenu(wxTreeListEvent& event); | |
197 | ||
198 | ||
199 | enum | |
200 | { | |
201 | Icon_File, | |
202 | Icon_FolderClosed, | |
203 | Icon_FolderOpened | |
204 | }; | |
205 | ||
206 | // Create the image list, called once only. Should add images to it in the | |
207 | // same order as they appear in the enum above. | |
208 | void InitImageList(); | |
209 | ||
210 | // Create the control with the given styles. | |
211 | wxTreeListCtrl* CreateTreeListCtrl(long style); | |
212 | ||
213 | // Recreate an already existing control. | |
214 | void RecreateTreeListCtrl(long style); | |
215 | ||
216 | // Helper: return the text of the item or "NONE" if the item is invalid. | |
217 | wxString DumpItem(wxTreeListItem item) const; | |
218 | ||
219 | // Another helper: just translate wxCheckBoxState to user-readable text. | |
220 | static const char* CheckedStateString(wxCheckBoxState state); | |
221 | ||
222 | ||
223 | wxImageList* m_imageList; | |
224 | ||
225 | wxTreeListCtrl* m_treelist; | |
226 | ||
227 | MyComparator m_comparator; | |
228 | ||
229 | wxTreeListItem m_itemHTMLDocs; | |
230 | ||
231 | wxLog* m_oldLogTarget; | |
232 | ||
233 | bool m_isFlat; | |
234 | ||
235 | wxDECLARE_EVENT_TABLE(); | |
236 | }; | |
237 | ||
238 | // ============================================================================ | |
239 | // Implementation | |
240 | // ============================================================================ | |
241 | ||
242 | // ---------------------------------------------------------------------------- | |
243 | // Application class | |
244 | // ---------------------------------------------------------------------------- | |
245 | ||
246 | wxIMPLEMENT_APP(MyApp); | |
247 | ||
248 | bool MyApp::OnInit() | |
249 | { | |
250 | if ( !wxApp::OnInit() ) | |
251 | return false; | |
252 | ||
253 | new MyFrame; | |
254 | ||
255 | return true; | |
256 | } | |
257 | ||
258 | // ---------------------------------------------------------------------------- | |
259 | // Main window class | |
260 | // ---------------------------------------------------------------------------- | |
261 | ||
262 | BEGIN_EVENT_TABLE(MyFrame, wxFrame) | |
263 | EVT_MENU(Id_MultiSelect, MyFrame::OnMultiSelect) | |
264 | EVT_MENU(Id_FlatList, MyFrame::OnFlatList) | |
265 | EVT_MENU_RANGE(Id_Checkboxes_Start, Id_Checkboxes_End, | |
266 | MyFrame::OnCheckboxes) | |
267 | ||
268 | EVT_MENU(Id_DumpSelection, MyFrame::OnDumpSelection) | |
269 | EVT_MENU_RANGE(Id_Check_HTMLDocs, Id_Indet_HTMLDocs, | |
270 | MyFrame::OnCheckHTMLDocs) | |
271 | EVT_MENU(Id_Select_HTMLDocs, MyFrame::OnSelectHTMLDocs) | |
272 | ||
273 | EVT_MENU(wxID_ABOUT, MyFrame::OnAbout) | |
274 | EVT_MENU(wxID_EXIT, MyFrame::OnExit) | |
275 | ||
276 | EVT_TREELIST_SELECTION_CHANGED(wxID_ANY, MyFrame::OnSelectionChanged) | |
277 | EVT_TREELIST_ITEM_EXPANDING(wxID_ANY, MyFrame::OnItemExpanding) | |
278 | EVT_TREELIST_ITEM_EXPANDED(wxID_ANY, MyFrame::OnItemExpanded) | |
279 | EVT_TREELIST_ITEM_CHECKED(wxID_ANY, MyFrame::OnItemChecked) | |
280 | EVT_TREELIST_ITEM_ACTIVATED(wxID_ANY, MyFrame::OnItemActivated) | |
281 | EVT_TREELIST_ITEM_CONTEXT_MENU(wxID_ANY, MyFrame::OnItemContextMenu) | |
282 | END_EVENT_TABLE() | |
283 | ||
284 | MyFrame::MyFrame() | |
285 | : wxFrame(NULL, wxID_ANY, "wxWidgets tree/list control sample", | |
286 | wxDefaultPosition, wxSize(600, 450)) | |
287 | { | |
288 | m_isFlat = false; | |
289 | ||
290 | // Create menus and status bar. | |
291 | SetIcon(wxICON(sample)); | |
292 | ||
293 | wxMenu* fileMenu = new wxMenu; | |
294 | fileMenu->Append(wxID_EXIT); | |
295 | ||
296 | wxMenu* treeStyle = new wxMenu; | |
297 | treeStyle->AppendCheckItem(Id_MultiSelect, "&Multiple selections\tCtrl-M"); | |
298 | treeStyle->AppendSeparator(); | |
299 | treeStyle->AppendRadioItem(Id_NoCheckboxes, | |
300 | "&No checkboxes\tCtrl-1"); | |
301 | treeStyle->AppendRadioItem(Id_Checkboxes2State, | |
302 | "&2-state checkboxes\tCtrl-2"); | |
303 | treeStyle->AppendRadioItem(Id_Checkboxes3State, | |
304 | "&3-state checkboxes\tCtrl-3"); | |
305 | treeStyle->AppendRadioItem(Id_CheckboxesUser3State, | |
306 | "&User-settable 3-state checkboxes\tCtrl-4"); | |
307 | treeStyle->AppendSeparator(); | |
308 | treeStyle->AppendCheckItem(Id_FlatList, "&Flat list"); | |
309 | ||
310 | wxMenu* treeOper = new wxMenu; | |
311 | treeOper->Append(Id_DumpSelection, "&Dump selection\tCtrl-D"); | |
312 | treeOper->AppendSeparator(); | |
313 | treeOper->Append(Id_Check_HTMLDocs, "&Check Doc/HTML item\tCtrl-C"); | |
314 | treeOper->Append(Id_Uncheck_HTMLDocs, "&Uncheck Doc/HTML item\tCtrl-U"); | |
315 | treeOper->Append(Id_Indet_HTMLDocs, "Make Doc/HTML &indeterminate\tCtrl-I"); | |
316 | treeOper->Append(Id_Select_HTMLDocs, "&Select Doc/HTML item\tCtrl-S"); | |
317 | ||
318 | wxMenu* helpMenu = new wxMenu; | |
319 | helpMenu->Append(wxID_ABOUT); | |
320 | ||
321 | wxMenuBar* menuBar = new wxMenuBar(); | |
322 | menuBar->Append(fileMenu, "&File"); | |
323 | menuBar->Append(treeStyle, "&Style"); | |
324 | menuBar->Append(treeOper, "&Operations"); | |
325 | menuBar->Append(helpMenu, "&Help"); | |
326 | SetMenuBar(menuBar); | |
327 | ||
328 | CreateStatusBar(1); | |
329 | ||
330 | ||
331 | // Construct the image list with the standard images. | |
332 | InitImageList(); | |
333 | ||
334 | ||
335 | // Create and layout child controls. | |
336 | m_treelist = CreateTreeListCtrl(wxTL_DEFAULT_STYLE); | |
337 | ||
338 | wxTextCtrl* textLog = new wxTextCtrl(this, wxID_ANY, "", | |
339 | wxDefaultPosition, wxDefaultSize, | |
340 | wxTE_READONLY | wxTE_MULTILINE); | |
341 | m_oldLogTarget = wxLog::SetActiveTarget(new wxLogTextCtrl(textLog)); | |
342 | ||
343 | wxSizer* sizer = new wxBoxSizer(wxVERTICAL); | |
344 | sizer->Add(m_treelist, wxSizerFlags(2).Expand()); | |
345 | sizer->Add(textLog, wxSizerFlags(1).Expand()); | |
346 | SetSizer(sizer); | |
347 | ||
348 | ||
349 | // Finally show everything. | |
350 | Show(); | |
351 | } | |
352 | ||
353 | MyFrame::~MyFrame() | |
354 | { | |
355 | delete m_imageList; | |
356 | ||
357 | delete wxLog::SetActiveTarget(m_oldLogTarget); | |
358 | } | |
359 | ||
360 | void MyFrame::InitImageList() | |
361 | { | |
362 | wxSize iconSize = wxArtProvider::GetSizeHint(wxART_LIST); | |
363 | if ( iconSize == wxDefaultSize ) | |
364 | iconSize = wxSize(16, 16); | |
365 | ||
366 | m_imageList = new wxImageList(iconSize.x, iconSize.y); | |
367 | ||
368 | // The order should be the same as for the enum elements. | |
369 | static const char* const icons[] = | |
370 | { | |
371 | wxART_NORMAL_FILE, | |
372 | wxART_FOLDER, | |
373 | wxART_FOLDER_OPEN | |
374 | }; | |
375 | ||
376 | for ( unsigned n = 0; n < WXSIZEOF(icons); n++ ) | |
377 | { | |
378 | m_imageList->Add | |
379 | ( | |
380 | wxArtProvider::GetIcon(icons[n], wxART_LIST, iconSize) | |
381 | ); | |
382 | } | |
383 | } | |
384 | ||
385 | wxTreeListCtrl* MyFrame::CreateTreeListCtrl(long style) | |
386 | { | |
387 | wxTreeListCtrl* const | |
388 | tree = new wxTreeListCtrl(this, wxID_ANY, | |
389 | wxDefaultPosition, wxDefaultSize, | |
390 | style); | |
391 | tree->SetImageList(m_imageList); | |
392 | ||
393 | tree->AppendColumn("Component", | |
394 | wxCOL_WIDTH_AUTOSIZE, | |
395 | wxALIGN_LEFT, | |
396 | wxCOL_RESIZABLE | wxCOL_SORTABLE); | |
397 | tree->AppendColumn("# Files", | |
398 | tree->WidthFor("1,000,000"), | |
399 | wxALIGN_RIGHT, | |
400 | wxCOL_RESIZABLE | wxCOL_SORTABLE); | |
401 | tree->AppendColumn("Size", | |
402 | tree->WidthFor("1,000,000 KiB"), | |
403 | wxALIGN_RIGHT, | |
404 | wxCOL_RESIZABLE | wxCOL_SORTABLE); | |
405 | ||
406 | // Define a shortcut to save on typing here. | |
407 | #define ADD_ITEM(item, parent, files, size) \ | |
408 | wxTreeListItem item = tree->AppendItem(m_isFlat ? root : parent, \ | |
409 | #item, \ | |
410 | Icon_FolderClosed, \ | |
411 | Icon_FolderOpened); \ | |
412 | tree->SetItemText(item, Col_Files, files); \ | |
413 | tree->SetItemText(item, Col_Size, size) | |
414 | ||
415 | wxTreeListItem root = tree->GetRootItem(); | |
416 | ADD_ITEM(Code, root, "", ""); | |
417 | ADD_ITEM(wxMSW, Code, "313", "3.94 MiB"); | |
418 | ADD_ITEM(wxGTK, Code, "180", "1.66 MiB"); | |
419 | ||
420 | ADD_ITEM(wxOSX, Code, "265", "2.36 MiB"); | |
421 | ADD_ITEM(Core, wxOSX, "31", "347 KiB"); | |
422 | ADD_ITEM(Carbon, wxOSX, "91", "1.34 MiB"); | |
423 | ADD_ITEM(Cocoa, wxOSX, "46", "512 KiB"); | |
424 | ||
425 | ADD_ITEM(Documentation, root, "", ""); | |
426 | ADD_ITEM(HTML, Documentation, "many", ""); | |
427 | ADD_ITEM(CHM, Documentation, "1", ""); | |
428 | ||
429 | ADD_ITEM(Samples, root, "", ""); | |
430 | ADD_ITEM(minimal, Samples, "1", "7 KiB"); | |
431 | ADD_ITEM(widgets, Samples, "28", "419 KiB"); | |
432 | ||
433 | #undef ADD_ITEM | |
434 | ||
435 | // Remember this one for subsequent tests. | |
436 | m_itemHTMLDocs = HTML; | |
437 | ||
438 | // Set a custom comparator to compare strings containing numbers correctly. | |
439 | tree->SetItemComparator(&m_comparator); | |
440 | ||
441 | return tree; | |
442 | } | |
443 | ||
444 | void MyFrame::RecreateTreeListCtrl(long style) | |
445 | { | |
446 | wxTreeListCtrl* const treelist = CreateTreeListCtrl(style); | |
447 | GetSizer()->Replace(m_treelist, treelist); | |
448 | ||
449 | delete m_treelist; | |
450 | m_treelist = treelist; | |
451 | ||
452 | Layout(); | |
453 | } | |
454 | ||
455 | void MyFrame::OnMultiSelect(wxCommandEvent& event) | |
456 | { | |
457 | long style = m_treelist->GetWindowStyle(); | |
458 | ||
459 | if ( event.IsChecked() ) | |
460 | style |= wxTL_MULTIPLE; | |
461 | else | |
462 | style &= ~wxTL_MULTIPLE; | |
463 | ||
464 | RecreateTreeListCtrl(style); | |
465 | } | |
466 | ||
467 | void MyFrame::OnFlatList(wxCommandEvent& event) | |
468 | { | |
469 | m_isFlat = event.IsChecked(); | |
470 | ||
471 | RecreateTreeListCtrl(m_treelist->GetWindowStyle()); | |
472 | } | |
473 | ||
474 | void MyFrame::OnCheckboxes(wxCommandEvent& event) | |
475 | { | |
476 | long style = m_treelist->GetWindowStyle(); | |
477 | style &= ~(wxTL_CHECKBOX | wxTL_3STATE | wxTL_USER_3STATE); | |
478 | ||
479 | switch ( event.GetId() ) | |
480 | { | |
481 | case Id_NoCheckboxes: | |
482 | break; | |
483 | ||
484 | case Id_Checkboxes2State: | |
485 | style |= wxTL_CHECKBOX; | |
486 | break; | |
487 | ||
488 | case Id_Checkboxes3State: | |
489 | style |= wxTL_3STATE; | |
490 | break; | |
491 | ||
492 | case Id_CheckboxesUser3State: | |
493 | style |= wxTL_USER_3STATE; | |
494 | break; | |
495 | ||
496 | default: | |
497 | wxFAIL_MSG( "Unknown checkbox style" ); | |
498 | return; | |
499 | } | |
500 | ||
501 | RecreateTreeListCtrl(style); | |
502 | } | |
503 | ||
504 | void MyFrame::OnDumpSelection(wxCommandEvent& WXUNUSED(event)) | |
505 | { | |
506 | if ( m_treelist->HasFlag(wxTL_MULTIPLE) ) | |
507 | { | |
508 | wxTreeListItems selections; | |
509 | const unsigned numSelected = m_treelist->GetSelections(selections); | |
510 | ||
511 | switch ( numSelected ) | |
512 | { | |
513 | case 0: | |
514 | wxLogMessage("No items selected"); | |
515 | break; | |
516 | ||
517 | case 1: | |
518 | wxLogMessage("Single item selected: %s", | |
519 | DumpItem(selections[0])); | |
520 | break; | |
521 | ||
522 | default: | |
523 | wxLogMessage("%u items selected:", numSelected); | |
524 | for ( unsigned n = 0; n < numSelected; n++ ) | |
525 | { | |
526 | wxLogMessage("\t%s", DumpItem(selections[n])); | |
527 | } | |
528 | } | |
529 | } | |
530 | else // Single selection | |
531 | { | |
532 | wxLogMessage("Selection: %s", DumpItem(m_treelist->GetSelection())); | |
533 | } | |
534 | } | |
535 | ||
536 | void MyFrame::OnCheckHTMLDocs(wxCommandEvent& event) | |
537 | { | |
538 | wxCheckBoxState state; | |
539 | ||
540 | switch ( event.GetId() ) | |
541 | { | |
542 | case Id_Uncheck_HTMLDocs: | |
543 | state = wxCHK_UNCHECKED; | |
544 | break; | |
545 | ||
546 | case Id_Check_HTMLDocs: | |
547 | state = wxCHK_CHECKED; | |
548 | break; | |
549 | ||
550 | case Id_Indet_HTMLDocs: | |
551 | state = wxCHK_UNDETERMINED; | |
552 | break; | |
553 | ||
554 | default: | |
555 | wxFAIL_MSG( "Unknown check state" ); | |
556 | return; | |
557 | } | |
558 | ||
559 | m_treelist->CheckItem(m_itemHTMLDocs, state); | |
560 | } | |
561 | ||
562 | void MyFrame::OnSelectHTMLDocs(wxCommandEvent& WXUNUSED(event)) | |
563 | { | |
564 | m_treelist->Select(m_itemHTMLDocs); | |
565 | } | |
566 | ||
567 | void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) | |
568 | { | |
569 | wxAboutDialogInfo info; | |
570 | info.SetDescription("wxTreeListCtrl wxWidgets sample."); | |
571 | info.SetCopyright("(C) 2011 Vadim Zeitlin <vadim@wxwidgets.org>"); | |
572 | ||
573 | wxAboutBox(info); | |
574 | } | |
575 | ||
576 | void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event)) | |
577 | { | |
578 | Close(true); | |
579 | } | |
580 | ||
581 | wxString MyFrame::DumpItem(wxTreeListItem item) const | |
582 | { | |
583 | return item.IsOk() ? m_treelist->GetItemText(item) : wxString("NONE"); | |
584 | } | |
585 | ||
586 | /* static */ | |
587 | const char* MyFrame::CheckedStateString(wxCheckBoxState state) | |
588 | { | |
589 | switch ( state ) | |
590 | { | |
591 | case wxCHK_UNCHECKED: | |
592 | return "unchecked"; | |
593 | ||
594 | case wxCHK_UNDETERMINED: | |
595 | return "undetermined"; | |
596 | ||
597 | case wxCHK_CHECKED: | |
598 | return "checked"; | |
599 | } | |
600 | ||
601 | return "invalid"; | |
602 | } | |
603 | ||
604 | void MyFrame::OnSelectionChanged(wxTreeListEvent& event) | |
605 | { | |
606 | const char* msg; | |
607 | ||
608 | if ( m_treelist->HasFlag(wxTL_MULTIPLE) ) | |
609 | msg = "Selection of the \"%s\" item changed."; | |
610 | else | |
611 | msg = "Selection changed, now is \"%s\"."; | |
612 | ||
613 | wxLogMessage(msg, DumpItem(event.GetItem())); | |
614 | } | |
615 | ||
616 | void MyFrame::OnItemExpanding(wxTreeListEvent& event) | |
617 | { | |
618 | wxLogMessage("Item \"%s\" is expanding", DumpItem(event.GetItem())); | |
619 | } | |
620 | ||
621 | void MyFrame::OnItemExpanded(wxTreeListEvent& event) | |
622 | { | |
623 | wxLogMessage("Item \"%s\" expanded", DumpItem(event.GetItem())); | |
624 | } | |
625 | ||
626 | void MyFrame::OnItemChecked(wxTreeListEvent& event) | |
627 | { | |
628 | wxTreeListItem item = event.GetItem(); | |
629 | ||
630 | wxLogMessage("Item \"%s\" toggled, now %s (was %s)", | |
631 | DumpItem(item), | |
632 | CheckedStateString(m_treelist->GetCheckedState(item)), | |
633 | CheckedStateString(event.GetOldCheckedState())); | |
634 | } | |
635 | ||
636 | void MyFrame::OnItemActivated(wxTreeListEvent& event) | |
637 | { | |
638 | wxLogMessage("Item \"%s\" activated", DumpItem(event.GetItem())); | |
639 | } | |
640 | ||
641 | void MyFrame::OnItemContextMenu(wxTreeListEvent& event) | |
642 | { | |
643 | enum | |
644 | { | |
645 | Id_Check_Item, | |
646 | Id_Uncheck_Item, | |
647 | Id_Indet_Item, | |
648 | Id_Check_Recursively, | |
649 | Id_Update_Parent | |
650 | }; | |
651 | ||
652 | wxMenu menu; | |
653 | menu.Append(Id_Check_Item, "&Check item"); | |
654 | menu.Append(Id_Uncheck_Item, "&Uncheck item"); | |
655 | if ( m_treelist->HasFlag(wxTL_3STATE) ) | |
656 | menu.Append(Id_Indet_Item, "Make item &indeterminate"); | |
657 | menu.AppendSeparator(); | |
658 | menu.Append(Id_Check_Recursively, "Check &recursively"); | |
659 | menu.Append(Id_Update_Parent, "Update &parent"); | |
660 | ||
661 | const wxTreeListItem item = event.GetItem(); | |
662 | switch ( m_treelist->GetPopupMenuSelectionFromUser(menu) ) | |
663 | { | |
664 | case Id_Check_Item: | |
665 | m_treelist->CheckItem(item); | |
666 | break; | |
667 | ||
668 | case Id_Uncheck_Item: | |
669 | m_treelist->UncheckItem(item); | |
670 | break; | |
671 | ||
672 | case Id_Indet_Item: | |
673 | m_treelist->CheckItem(item, wxCHK_UNDETERMINED); | |
674 | break; | |
675 | ||
676 | case Id_Check_Recursively: | |
677 | m_treelist->CheckItemRecursively(item); | |
678 | break; | |
679 | ||
680 | case Id_Update_Parent: | |
681 | m_treelist->UpdateItemParentStateRecursively(item); | |
682 | break; | |
683 | ||
684 | default: | |
685 | wxFAIL_MSG( "Unexpected menu selection" ); | |
686 | // Fall through. | |
687 | ||
688 | case wxID_NONE: | |
689 | return; | |
690 | } | |
691 | } |