2011-08-27 10:11:03 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: samples/treelist/treelist.cpp
|
|
|
|
// Purpose: Sample showing wxTreeListCtrl.
|
|
|
|
// Author: Vadim Zeitlin
|
|
|
|
// Created: 2011-08-19
|
|
|
|
// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
|
|
|
|
// Licence: wxWindows licence
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// Declarations
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Headers
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
|
|
|
|
|
|
#if !wxUSE_TREELISTCTRL
|
|
|
|
#error "wxUSE_TREELISTCTRL must be 1 for this sample."
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef WX_PRECOMP
|
|
|
|
#include "wx/app.h"
|
|
|
|
#include "wx/frame.h"
|
|
|
|
#include "wx/log.h"
|
|
|
|
#include "wx/menu.h"
|
|
|
|
#include "wx/sizer.h"
|
|
|
|
#include "wx/statusbr.h"
|
|
|
|
#include "wx/textctrl.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "wx/treelist.h"
|
|
|
|
|
|
|
|
#include "wx/aboutdlg.h"
|
|
|
|
#include "wx/artprov.h"
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Resources
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2012-03-03 19:28:58 -05:00
|
|
|
#ifndef wxHAS_IMAGES_IN_RESOURCES
|
2011-08-27 10:11:03 -04:00
|
|
|
#include "../sample.xpm"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2011-09-21 11:07:53 -04:00
|
|
|
// Constants
|
2011-08-27 10:11:03 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2011-09-21 11:07:53 -04:00
|
|
|
// Menu items.
|
2011-08-27 10:11:03 -04:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
Id_MultiSelect = 100,
|
2011-08-30 09:40:44 -04:00
|
|
|
Id_FlatList,
|
2011-08-27 10:11:03 -04:00
|
|
|
|
|
|
|
Id_Checkboxes_Start,
|
|
|
|
Id_NoCheckboxes = Id_Checkboxes_Start,
|
|
|
|
Id_Checkboxes2State,
|
|
|
|
Id_Checkboxes3State,
|
|
|
|
Id_CheckboxesUser3State,
|
|
|
|
Id_Checkboxes_End,
|
|
|
|
|
2018-01-24 11:59:25 -05:00
|
|
|
Id_DeleteAllItems,
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
Id_DumpSelection,
|
|
|
|
Id_Check_HTMLDocs,
|
|
|
|
Id_Uncheck_HTMLDocs,
|
|
|
|
Id_Indet_HTMLDocs,
|
|
|
|
Id_Select_HTMLDocs
|
|
|
|
};
|
|
|
|
|
2011-09-21 11:07:53 -04:00
|
|
|
// Tree list columns.
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
Col_Component,
|
|
|
|
Col_Files,
|
|
|
|
Col_Size
|
|
|
|
};
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Custom comparator for tree list items comparison
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// This is a toy class as in a real program you would have the original numeric
|
|
|
|
// data somewhere and wouldn't need to parse it back from strings presumably.
|
|
|
|
// Nevertheless it shows how to implement a custom comparator which is needed
|
|
|
|
// if you want to sort by a column with non-textual contents.
|
|
|
|
class MyComparator : public wxTreeListItemComparator
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual int
|
|
|
|
Compare(wxTreeListCtrl* treelist,
|
|
|
|
unsigned column,
|
|
|
|
wxTreeListItem item1,
|
2014-03-29 20:02:23 -04:00
|
|
|
wxTreeListItem item2) wxOVERRIDE
|
2011-09-21 11:07:53 -04:00
|
|
|
{
|
|
|
|
wxString text1 = treelist->GetItemText(item1, column),
|
|
|
|
text2 = treelist->GetItemText(item2, column);
|
|
|
|
|
|
|
|
switch ( column )
|
|
|
|
{
|
|
|
|
case Col_Component:
|
|
|
|
// Simple alphabetical comparison is fine for those.
|
|
|
|
return text1.CmpNoCase(text2);
|
|
|
|
|
|
|
|
case Col_Files:
|
|
|
|
// Compare strings as numbers.
|
|
|
|
return GetNumFilesFromText(text1) - GetNumFilesFromText(text2);
|
|
|
|
|
|
|
|
case Col_Size:
|
|
|
|
// Compare strings as numbers but also take care of "KiB" and
|
|
|
|
// "MiB" suffixes.
|
|
|
|
return GetSizeFromText(text1) - GetSizeFromText(text2);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFAIL_MSG( "Sorting on unknown column?" );
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Return the number of files handling special value "many". Notice that
|
|
|
|
// the returned value is signed to allow using it in subtraction above.
|
|
|
|
int GetNumFilesFromText(const wxString& text) const
|
|
|
|
{
|
|
|
|
unsigned long n;
|
|
|
|
if ( !text.ToULong(&n) )
|
|
|
|
{
|
|
|
|
if ( text == "many" )
|
|
|
|
n = 9999;
|
|
|
|
else
|
|
|
|
n = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the size in KiB from a string with either KiB or MiB suffix.
|
|
|
|
int GetSizeFromText(const wxString& text) const
|
|
|
|
{
|
|
|
|
wxString size;
|
|
|
|
unsigned factor = 1;
|
|
|
|
if ( text.EndsWith(" MiB", &size) )
|
|
|
|
factor = 1024;
|
|
|
|
else if ( !text.EndsWith(" KiB", &size) )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
unsigned long n = 0;
|
|
|
|
size.ToULong(&n);
|
|
|
|
|
|
|
|
return n*factor;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Application class
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class MyApp : public wxApp
|
|
|
|
{
|
|
|
|
public:
|
2014-03-29 20:02:23 -04:00
|
|
|
virtual bool OnInit() wxOVERRIDE;
|
2011-08-27 10:11:03 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Main window class
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class MyFrame : public wxFrame
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MyFrame();
|
|
|
|
virtual ~MyFrame();
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Event handlers for the menu and wxTreeListCtrl events.
|
|
|
|
void OnMultiSelect(wxCommandEvent& event);
|
2011-08-30 09:40:44 -04:00
|
|
|
void OnFlatList(wxCommandEvent& event);
|
2011-08-27 10:11:03 -04:00
|
|
|
void OnCheckboxes(wxCommandEvent& event);
|
|
|
|
void OnDumpSelection(wxCommandEvent& event);
|
|
|
|
void OnCheckHTMLDocs(wxCommandEvent& event);
|
|
|
|
void OnSelectHTMLDocs(wxCommandEvent& event);
|
|
|
|
|
|
|
|
void OnAbout(wxCommandEvent& event);
|
|
|
|
void OnExit(wxCommandEvent& event);
|
|
|
|
|
2018-01-24 11:59:25 -05:00
|
|
|
void OnDeleteAllItems(wxCommandEvent& event);
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
void OnSelectionChanged(wxTreeListEvent& event);
|
|
|
|
void OnItemExpanding(wxTreeListEvent& event);
|
|
|
|
void OnItemExpanded(wxTreeListEvent& event);
|
|
|
|
void OnItemChecked(wxTreeListEvent& event);
|
|
|
|
void OnItemActivated(wxTreeListEvent& event);
|
|
|
|
void OnItemContextMenu(wxTreeListEvent& event);
|
|
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
Icon_File,
|
|
|
|
Icon_FolderClosed,
|
|
|
|
Icon_FolderOpened
|
|
|
|
};
|
|
|
|
|
|
|
|
// Create the image list, called once only. Should add images to it in the
|
|
|
|
// same order as they appear in the enum above.
|
|
|
|
void InitImageList();
|
|
|
|
|
|
|
|
// Create the control with the given styles.
|
|
|
|
wxTreeListCtrl* CreateTreeListCtrl(long style);
|
|
|
|
|
|
|
|
// Recreate an already existing control.
|
|
|
|
void RecreateTreeListCtrl(long style);
|
|
|
|
|
|
|
|
// Helper: return the text of the item or "NONE" if the item is invalid.
|
|
|
|
wxString DumpItem(wxTreeListItem item) const;
|
|
|
|
|
|
|
|
// Another helper: just translate wxCheckBoxState to user-readable text.
|
|
|
|
static const char* CheckedStateString(wxCheckBoxState state);
|
|
|
|
|
|
|
|
|
|
|
|
wxImageList* m_imageList;
|
|
|
|
|
|
|
|
wxTreeListCtrl* m_treelist;
|
|
|
|
|
2011-09-21 11:07:53 -04:00
|
|
|
MyComparator m_comparator;
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
wxTreeListItem m_itemHTMLDocs;
|
|
|
|
|
|
|
|
wxLog* m_oldLogTarget;
|
|
|
|
|
2011-08-30 09:40:44 -04:00
|
|
|
bool m_isFlat;
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
wxDECLARE_EVENT_TABLE();
|
|
|
|
};
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// Implementation
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Application class
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
wxIMPLEMENT_APP(MyApp);
|
|
|
|
|
|
|
|
bool MyApp::OnInit()
|
|
|
|
{
|
|
|
|
if ( !wxApp::OnInit() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
new MyFrame;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Main window class
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2014-03-30 03:07:55 -04:00
|
|
|
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
2011-08-27 10:11:03 -04:00
|
|
|
EVT_MENU(Id_MultiSelect, MyFrame::OnMultiSelect)
|
2011-08-30 09:40:44 -04:00
|
|
|
EVT_MENU(Id_FlatList, MyFrame::OnFlatList)
|
2011-08-27 10:11:03 -04:00
|
|
|
EVT_MENU_RANGE(Id_Checkboxes_Start, Id_Checkboxes_End,
|
|
|
|
MyFrame::OnCheckboxes)
|
|
|
|
|
|
|
|
EVT_MENU(Id_DumpSelection, MyFrame::OnDumpSelection)
|
|
|
|
EVT_MENU_RANGE(Id_Check_HTMLDocs, Id_Indet_HTMLDocs,
|
|
|
|
MyFrame::OnCheckHTMLDocs)
|
|
|
|
EVT_MENU(Id_Select_HTMLDocs, MyFrame::OnSelectHTMLDocs)
|
|
|
|
|
|
|
|
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
|
|
|
|
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
|
|
|
|
|
2018-01-24 11:59:25 -05:00
|
|
|
EVT_MENU(Id_DeleteAllItems, MyFrame::OnDeleteAllItems)
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
EVT_TREELIST_SELECTION_CHANGED(wxID_ANY, MyFrame::OnSelectionChanged)
|
|
|
|
EVT_TREELIST_ITEM_EXPANDING(wxID_ANY, MyFrame::OnItemExpanding)
|
|
|
|
EVT_TREELIST_ITEM_EXPANDED(wxID_ANY, MyFrame::OnItemExpanded)
|
|
|
|
EVT_TREELIST_ITEM_CHECKED(wxID_ANY, MyFrame::OnItemChecked)
|
|
|
|
EVT_TREELIST_ITEM_ACTIVATED(wxID_ANY, MyFrame::OnItemActivated)
|
|
|
|
EVT_TREELIST_ITEM_CONTEXT_MENU(wxID_ANY, MyFrame::OnItemContextMenu)
|
2014-03-30 03:07:55 -04:00
|
|
|
wxEND_EVENT_TABLE()
|
2011-08-27 10:11:03 -04:00
|
|
|
|
|
|
|
MyFrame::MyFrame()
|
|
|
|
: wxFrame(NULL, wxID_ANY, "wxWidgets tree/list control sample",
|
|
|
|
wxDefaultPosition, wxSize(600, 450))
|
|
|
|
{
|
2011-08-30 09:40:44 -04:00
|
|
|
m_isFlat = false;
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
// Create menus and status bar.
|
|
|
|
SetIcon(wxICON(sample));
|
|
|
|
|
|
|
|
wxMenu* fileMenu = new wxMenu;
|
|
|
|
fileMenu->Append(wxID_EXIT);
|
|
|
|
|
|
|
|
wxMenu* treeStyle = new wxMenu;
|
|
|
|
treeStyle->AppendCheckItem(Id_MultiSelect, "&Multiple selections\tCtrl-M");
|
|
|
|
treeStyle->AppendSeparator();
|
|
|
|
treeStyle->AppendRadioItem(Id_NoCheckboxes,
|
|
|
|
"&No checkboxes\tCtrl-1");
|
|
|
|
treeStyle->AppendRadioItem(Id_Checkboxes2State,
|
|
|
|
"&2-state checkboxes\tCtrl-2");
|
|
|
|
treeStyle->AppendRadioItem(Id_Checkboxes3State,
|
|
|
|
"&3-state checkboxes\tCtrl-3");
|
|
|
|
treeStyle->AppendRadioItem(Id_CheckboxesUser3State,
|
|
|
|
"&User-settable 3-state checkboxes\tCtrl-4");
|
2011-08-30 09:40:44 -04:00
|
|
|
treeStyle->AppendSeparator();
|
|
|
|
treeStyle->AppendCheckItem(Id_FlatList, "&Flat list");
|
2011-08-27 10:11:03 -04:00
|
|
|
|
|
|
|
wxMenu* treeOper = new wxMenu;
|
|
|
|
treeOper->Append(Id_DumpSelection, "&Dump selection\tCtrl-D");
|
|
|
|
treeOper->AppendSeparator();
|
|
|
|
treeOper->Append(Id_Check_HTMLDocs, "&Check Doc/HTML item\tCtrl-C");
|
|
|
|
treeOper->Append(Id_Uncheck_HTMLDocs, "&Uncheck Doc/HTML item\tCtrl-U");
|
|
|
|
treeOper->Append(Id_Indet_HTMLDocs, "Make Doc/HTML &indeterminate\tCtrl-I");
|
|
|
|
treeOper->Append(Id_Select_HTMLDocs, "&Select Doc/HTML item\tCtrl-S");
|
|
|
|
|
2018-01-24 11:59:25 -05:00
|
|
|
treeOper->Append(Id_DeleteAllItems, "DeleteAllItems");
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
wxMenu* helpMenu = new wxMenu;
|
|
|
|
helpMenu->Append(wxID_ABOUT);
|
|
|
|
|
|
|
|
wxMenuBar* menuBar = new wxMenuBar();
|
|
|
|
menuBar->Append(fileMenu, "&File");
|
|
|
|
menuBar->Append(treeStyle, "&Style");
|
|
|
|
menuBar->Append(treeOper, "&Operations");
|
|
|
|
menuBar->Append(helpMenu, "&Help");
|
|
|
|
SetMenuBar(menuBar);
|
|
|
|
|
|
|
|
CreateStatusBar(1);
|
|
|
|
|
|
|
|
|
|
|
|
// Construct the image list with the standard images.
|
|
|
|
InitImageList();
|
|
|
|
|
|
|
|
|
|
|
|
// Create and layout child controls.
|
|
|
|
m_treelist = CreateTreeListCtrl(wxTL_DEFAULT_STYLE);
|
|
|
|
|
|
|
|
wxTextCtrl* textLog = new wxTextCtrl(this, wxID_ANY, "",
|
|
|
|
wxDefaultPosition, wxDefaultSize,
|
|
|
|
wxTE_READONLY | wxTE_MULTILINE);
|
|
|
|
m_oldLogTarget = wxLog::SetActiveTarget(new wxLogTextCtrl(textLog));
|
|
|
|
|
|
|
|
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
|
|
|
sizer->Add(m_treelist, wxSizerFlags(2).Expand());
|
|
|
|
sizer->Add(textLog, wxSizerFlags(1).Expand());
|
|
|
|
SetSizer(sizer);
|
|
|
|
|
|
|
|
|
|
|
|
// Finally show everything.
|
|
|
|
Show();
|
|
|
|
}
|
|
|
|
|
|
|
|
MyFrame::~MyFrame()
|
|
|
|
{
|
|
|
|
delete m_imageList;
|
|
|
|
|
|
|
|
delete wxLog::SetActiveTarget(m_oldLogTarget);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::InitImageList()
|
|
|
|
{
|
2022-03-23 19:31:23 -04:00
|
|
|
wxSize iconSize = wxArtProvider::GetSizeHint(wxART_LIST, this);
|
2011-08-27 10:11:03 -04:00
|
|
|
if ( iconSize == wxDefaultSize )
|
2022-03-23 19:31:23 -04:00
|
|
|
iconSize = FromDIP(wxSize(16, 16));
|
2011-08-27 10:11:03 -04:00
|
|
|
|
|
|
|
m_imageList = new wxImageList(iconSize.x, iconSize.y);
|
|
|
|
|
|
|
|
// The order should be the same as for the enum elements.
|
2019-10-22 06:34:29 -04:00
|
|
|
static const wxString icons[] =
|
2011-08-27 10:11:03 -04:00
|
|
|
{
|
|
|
|
wxART_NORMAL_FILE,
|
|
|
|
wxART_FOLDER,
|
|
|
|
wxART_FOLDER_OPEN
|
|
|
|
};
|
|
|
|
|
|
|
|
for ( unsigned n = 0; n < WXSIZEOF(icons); n++ )
|
|
|
|
{
|
|
|
|
m_imageList->Add
|
|
|
|
(
|
|
|
|
wxArtProvider::GetIcon(icons[n], wxART_LIST, iconSize)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wxTreeListCtrl* MyFrame::CreateTreeListCtrl(long style)
|
|
|
|
{
|
|
|
|
wxTreeListCtrl* const
|
|
|
|
tree = new wxTreeListCtrl(this, wxID_ANY,
|
|
|
|
wxDefaultPosition, wxDefaultSize,
|
|
|
|
style);
|
|
|
|
tree->SetImageList(m_imageList);
|
|
|
|
|
2011-09-21 11:07:53 -04:00
|
|
|
tree->AppendColumn("Component",
|
|
|
|
wxCOL_WIDTH_AUTOSIZE,
|
|
|
|
wxALIGN_LEFT,
|
|
|
|
wxCOL_RESIZABLE | wxCOL_SORTABLE);
|
2011-08-27 10:11:03 -04:00
|
|
|
tree->AppendColumn("# Files",
|
|
|
|
tree->WidthFor("1,000,000"),
|
2011-09-21 11:07:53 -04:00
|
|
|
wxALIGN_RIGHT,
|
|
|
|
wxCOL_RESIZABLE | wxCOL_SORTABLE);
|
2011-08-27 10:11:03 -04:00
|
|
|
tree->AppendColumn("Size",
|
|
|
|
tree->WidthFor("1,000,000 KiB"),
|
2011-09-21 11:07:53 -04:00
|
|
|
wxALIGN_RIGHT,
|
|
|
|
wxCOL_RESIZABLE | wxCOL_SORTABLE);
|
2011-08-27 10:11:03 -04:00
|
|
|
|
|
|
|
// Define a shortcut to save on typing here.
|
|
|
|
#define ADD_ITEM(item, parent, files, size) \
|
2011-08-30 09:40:44 -04:00
|
|
|
wxTreeListItem item = tree->AppendItem(m_isFlat ? root : parent, \
|
|
|
|
#item, \
|
2011-08-27 10:11:03 -04:00
|
|
|
Icon_FolderClosed, \
|
|
|
|
Icon_FolderOpened); \
|
|
|
|
tree->SetItemText(item, Col_Files, files); \
|
|
|
|
tree->SetItemText(item, Col_Size, size)
|
|
|
|
|
|
|
|
wxTreeListItem root = tree->GetRootItem();
|
|
|
|
ADD_ITEM(Code, root, "", "");
|
|
|
|
ADD_ITEM(wxMSW, Code, "313", "3.94 MiB");
|
|
|
|
ADD_ITEM(wxGTK, Code, "180", "1.66 MiB");
|
|
|
|
|
|
|
|
ADD_ITEM(wxOSX, Code, "265", "2.36 MiB");
|
|
|
|
ADD_ITEM(Core, wxOSX, "31", "347 KiB");
|
|
|
|
ADD_ITEM(Carbon, wxOSX, "91", "1.34 MiB");
|
|
|
|
ADD_ITEM(Cocoa, wxOSX, "46", "512 KiB");
|
|
|
|
|
|
|
|
ADD_ITEM(Documentation, root, "", "");
|
|
|
|
ADD_ITEM(HTML, Documentation, "many", "");
|
|
|
|
ADD_ITEM(CHM, Documentation, "1", "");
|
|
|
|
|
|
|
|
ADD_ITEM(Samples, root, "", "");
|
|
|
|
ADD_ITEM(minimal, Samples, "1", "7 KiB");
|
|
|
|
ADD_ITEM(widgets, Samples, "28", "419 KiB");
|
|
|
|
|
|
|
|
#undef ADD_ITEM
|
|
|
|
|
|
|
|
// Remember this one for subsequent tests.
|
|
|
|
m_itemHTMLDocs = HTML;
|
|
|
|
|
2011-09-21 11:07:53 -04:00
|
|
|
// Set a custom comparator to compare strings containing numbers correctly.
|
|
|
|
tree->SetItemComparator(&m_comparator);
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
return tree;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::RecreateTreeListCtrl(long style)
|
|
|
|
{
|
|
|
|
wxTreeListCtrl* const treelist = CreateTreeListCtrl(style);
|
|
|
|
GetSizer()->Replace(m_treelist, treelist);
|
|
|
|
|
|
|
|
delete m_treelist;
|
|
|
|
m_treelist = treelist;
|
|
|
|
|
|
|
|
Layout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnMultiSelect(wxCommandEvent& event)
|
|
|
|
{
|
|
|
|
long style = m_treelist->GetWindowStyle();
|
|
|
|
|
|
|
|
if ( event.IsChecked() )
|
|
|
|
style |= wxTL_MULTIPLE;
|
|
|
|
else
|
|
|
|
style &= ~wxTL_MULTIPLE;
|
|
|
|
|
|
|
|
RecreateTreeListCtrl(style);
|
|
|
|
}
|
|
|
|
|
2011-08-30 09:40:44 -04:00
|
|
|
void MyFrame::OnFlatList(wxCommandEvent& event)
|
|
|
|
{
|
|
|
|
m_isFlat = event.IsChecked();
|
|
|
|
|
|
|
|
RecreateTreeListCtrl(m_treelist->GetWindowStyle());
|
|
|
|
}
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
void MyFrame::OnCheckboxes(wxCommandEvent& event)
|
|
|
|
{
|
|
|
|
long style = m_treelist->GetWindowStyle();
|
|
|
|
style &= ~(wxTL_CHECKBOX | wxTL_3STATE | wxTL_USER_3STATE);
|
|
|
|
|
|
|
|
switch ( event.GetId() )
|
|
|
|
{
|
|
|
|
case Id_NoCheckboxes:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Id_Checkboxes2State:
|
|
|
|
style |= wxTL_CHECKBOX;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Id_Checkboxes3State:
|
|
|
|
style |= wxTL_3STATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Id_CheckboxesUser3State:
|
|
|
|
style |= wxTL_USER_3STATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
wxFAIL_MSG( "Unknown checkbox style" );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
RecreateTreeListCtrl(style);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnDumpSelection(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
if ( m_treelist->HasFlag(wxTL_MULTIPLE) )
|
|
|
|
{
|
|
|
|
wxTreeListItems selections;
|
|
|
|
const unsigned numSelected = m_treelist->GetSelections(selections);
|
|
|
|
|
|
|
|
switch ( numSelected )
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
wxLogMessage("No items selected");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
wxLogMessage("Single item selected: %s",
|
|
|
|
DumpItem(selections[0]));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
wxLogMessage("%u items selected:", numSelected);
|
|
|
|
for ( unsigned n = 0; n < numSelected; n++ )
|
|
|
|
{
|
|
|
|
wxLogMessage("\t%s", DumpItem(selections[n]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // Single selection
|
|
|
|
{
|
|
|
|
wxLogMessage("Selection: %s", DumpItem(m_treelist->GetSelection()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnCheckHTMLDocs(wxCommandEvent& event)
|
|
|
|
{
|
|
|
|
wxCheckBoxState state;
|
|
|
|
|
|
|
|
switch ( event.GetId() )
|
|
|
|
{
|
|
|
|
case Id_Uncheck_HTMLDocs:
|
|
|
|
state = wxCHK_UNCHECKED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Id_Check_HTMLDocs:
|
|
|
|
state = wxCHK_CHECKED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Id_Indet_HTMLDocs:
|
|
|
|
state = wxCHK_UNDETERMINED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
wxFAIL_MSG( "Unknown check state" );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_treelist->CheckItem(m_itemHTMLDocs, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnSelectHTMLDocs(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
m_treelist->Select(m_itemHTMLDocs);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
wxAboutDialogInfo info;
|
|
|
|
info.SetDescription("wxTreeListCtrl wxWidgets sample.");
|
|
|
|
info.SetCopyright("(C) 2011 Vadim Zeitlin <vadim@wxwidgets.org>");
|
|
|
|
|
2017-03-20 18:27:57 -04:00
|
|
|
wxAboutBox(info, this);
|
2011-08-27 10:11:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
Close(true);
|
|
|
|
}
|
|
|
|
|
2018-01-24 11:59:25 -05:00
|
|
|
void MyFrame::OnDeleteAllItems(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
m_treelist->DeleteAllItems();
|
|
|
|
}
|
|
|
|
|
2011-08-27 10:11:03 -04:00
|
|
|
wxString MyFrame::DumpItem(wxTreeListItem item) const
|
|
|
|
{
|
|
|
|
return item.IsOk() ? m_treelist->GetItemText(item) : wxString("NONE");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
const char* MyFrame::CheckedStateString(wxCheckBoxState state)
|
|
|
|
{
|
|
|
|
switch ( state )
|
|
|
|
{
|
|
|
|
case wxCHK_UNCHECKED:
|
|
|
|
return "unchecked";
|
|
|
|
|
|
|
|
case wxCHK_UNDETERMINED:
|
|
|
|
return "undetermined";
|
|
|
|
|
|
|
|
case wxCHK_CHECKED:
|
|
|
|
return "checked";
|
|
|
|
}
|
|
|
|
|
|
|
|
return "invalid";
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnSelectionChanged(wxTreeListEvent& event)
|
|
|
|
{
|
2011-08-27 10:11:09 -04:00
|
|
|
const char* msg;
|
|
|
|
|
|
|
|
if ( m_treelist->HasFlag(wxTL_MULTIPLE) )
|
|
|
|
msg = "Selection of the \"%s\" item changed.";
|
|
|
|
else
|
|
|
|
msg = "Selection changed, now is \"%s\".";
|
|
|
|
|
|
|
|
wxLogMessage(msg, DumpItem(event.GetItem()));
|
2011-08-27 10:11:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnItemExpanding(wxTreeListEvent& event)
|
|
|
|
{
|
|
|
|
wxLogMessage("Item \"%s\" is expanding", DumpItem(event.GetItem()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnItemExpanded(wxTreeListEvent& event)
|
|
|
|
{
|
|
|
|
wxLogMessage("Item \"%s\" expanded", DumpItem(event.GetItem()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnItemChecked(wxTreeListEvent& event)
|
|
|
|
{
|
|
|
|
wxTreeListItem item = event.GetItem();
|
|
|
|
|
|
|
|
wxLogMessage("Item \"%s\" toggled, now %s (was %s)",
|
|
|
|
DumpItem(item),
|
|
|
|
CheckedStateString(m_treelist->GetCheckedState(item)),
|
|
|
|
CheckedStateString(event.GetOldCheckedState()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnItemActivated(wxTreeListEvent& event)
|
|
|
|
{
|
|
|
|
wxLogMessage("Item \"%s\" activated", DumpItem(event.GetItem()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnItemContextMenu(wxTreeListEvent& event)
|
|
|
|
{
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
Id_Check_Item,
|
|
|
|
Id_Uncheck_Item,
|
|
|
|
Id_Indet_Item,
|
|
|
|
Id_Check_Recursively,
|
|
|
|
Id_Update_Parent
|
|
|
|
};
|
|
|
|
|
|
|
|
wxMenu menu;
|
|
|
|
menu.Append(Id_Check_Item, "&Check item");
|
|
|
|
menu.Append(Id_Uncheck_Item, "&Uncheck item");
|
|
|
|
if ( m_treelist->HasFlag(wxTL_3STATE) )
|
|
|
|
menu.Append(Id_Indet_Item, "Make item &indeterminate");
|
|
|
|
menu.AppendSeparator();
|
|
|
|
menu.Append(Id_Check_Recursively, "Check &recursively");
|
|
|
|
menu.Append(Id_Update_Parent, "Update &parent");
|
|
|
|
|
|
|
|
const wxTreeListItem item = event.GetItem();
|
|
|
|
switch ( m_treelist->GetPopupMenuSelectionFromUser(menu) )
|
|
|
|
{
|
|
|
|
case Id_Check_Item:
|
|
|
|
m_treelist->CheckItem(item);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Id_Uncheck_Item:
|
|
|
|
m_treelist->UncheckItem(item);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Id_Indet_Item:
|
|
|
|
m_treelist->CheckItem(item, wxCHK_UNDETERMINED);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Id_Check_Recursively:
|
|
|
|
m_treelist->CheckItemRecursively(item);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Id_Update_Parent:
|
|
|
|
m_treelist->UpdateItemParentStateRecursively(item);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
wxFAIL_MSG( "Unexpected menu selection" );
|
2018-11-25 14:22:44 -05:00
|
|
|
wxFALLTHROUGH;
|
2011-08-27 10:11:03 -04:00
|
|
|
|
|
|
|
case wxID_NONE:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|