2881d9875a
This completes changes of 0873abb836
which
replaced manual layout code with sizers, but broke layout after
recreating the control in the process.
This change notably fixes the control becoming invisible, due to having
the default too small size, in non-report modes.
1499 lines
44 KiB
C++
1499 lines
44 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: listctrl.cpp
|
|
// Purpose: wxListCtrl sample
|
|
// Author: Julian Smart
|
|
// Modified by:
|
|
// Created: 04/01/98
|
|
// Copyright: (c) Julian Smart
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/wx.h"
|
|
#endif
|
|
|
|
#ifndef wxHAS_IMAGES_IN_RESOURCES
|
|
#include "../sample.xpm"
|
|
#endif
|
|
|
|
#ifndef wxHAS_IMAGES_IN_RESOURCES
|
|
#include "bitmaps/toolbrai.xpm"
|
|
#include "bitmaps/toolchar.xpm"
|
|
#include "bitmaps/tooldata.xpm"
|
|
#include "bitmaps/toolnote.xpm"
|
|
#include "bitmaps/tooltodo.xpm"
|
|
#include "bitmaps/toolchec.xpm"
|
|
#include "bitmaps/toolgame.xpm"
|
|
#include "bitmaps/tooltime.xpm"
|
|
#include "bitmaps/toolword.xpm"
|
|
#include "bitmaps/small1.xpm"
|
|
#endif
|
|
|
|
#include "wx/imaglist.h"
|
|
#include "wx/listctrl.h"
|
|
#include "wx/timer.h" // for wxStopWatch
|
|
#include "wx/colordlg.h" // for wxGetColourFromUser
|
|
#include "wx/settings.h"
|
|
#include "wx/sizer.h"
|
|
#include "wx/sysopt.h"
|
|
#include "wx/numdlg.h"
|
|
|
|
#include "listtest.h"
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Constants and globals
|
|
// ----------------------------------------------------------------------------
|
|
|
|
const wxChar *SMALL_VIRTUAL_VIEW_ITEMS[][2] =
|
|
{
|
|
{ wxT("Cat"), wxT("meow") },
|
|
{ wxT("Cow"), wxT("moo") },
|
|
{ wxT("Crow"), wxT("caw") },
|
|
{ wxT("Dog"), wxT("woof") },
|
|
{ wxT("Duck"), wxT("quack") },
|
|
{ wxT("Mouse"), wxT("squeak") },
|
|
{ wxT("Owl"), wxT("hoo") },
|
|
{ wxT("Pig"), wxT("oink") },
|
|
{ wxT("Pigeon"), wxT("coo") },
|
|
{ wxT("Sheep"), wxT("baaah") },
|
|
};
|
|
|
|
// number of items in icon/small icon view
|
|
static const int NUM_ICONS = 9;
|
|
|
|
int wxCALLBACK
|
|
MyCompareFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr WXUNUSED(sortData))
|
|
{
|
|
// inverse the order
|
|
if (item1 < item2)
|
|
return 1;
|
|
if (item1 > item2)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// MyApp
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_APP(MyApp);
|
|
|
|
// `Main program' equivalent, creating windows and returning main app frame
|
|
bool MyApp::OnInit()
|
|
{
|
|
if ( !wxApp::OnInit() )
|
|
return false;
|
|
|
|
// Create the main frame window
|
|
MyFrame *frame = new MyFrame(wxT("wxListCtrl Test"));
|
|
|
|
// Show the frame
|
|
frame->Show(true);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// MyFrame
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
|
EVT_MENU(LIST_QUIT, MyFrame::OnQuit)
|
|
EVT_MENU(LIST_ABOUT, MyFrame::OnAbout)
|
|
EVT_MENU(LIST_LIST_VIEW, MyFrame::OnListView)
|
|
EVT_MENU(LIST_REPORT_VIEW, MyFrame::OnReportView)
|
|
EVT_MENU(LIST_ICON_VIEW, MyFrame::OnIconView)
|
|
EVT_MENU(LIST_ICON_TEXT_VIEW, MyFrame::OnIconTextView)
|
|
EVT_MENU(LIST_SMALL_ICON_VIEW, MyFrame::OnSmallIconView)
|
|
EVT_MENU(LIST_SMALL_ICON_TEXT_VIEW, MyFrame::OnSmallIconTextView)
|
|
EVT_MENU(LIST_VIRTUAL_VIEW, MyFrame::OnVirtualView)
|
|
EVT_MENU(LIST_SMALL_VIRTUAL_VIEW, MyFrame::OnSmallVirtualView)
|
|
|
|
EVT_MENU(LIST_SET_ITEMS_COUNT, MyFrame::OnSetItemsCount)
|
|
|
|
EVT_MENU(LIST_GOTO, MyFrame::OnGoTo)
|
|
EVT_MENU(LIST_FOCUS_LAST, MyFrame::OnFocusLast)
|
|
EVT_MENU(LIST_TOGGLE_FIRST, MyFrame::OnToggleFirstSel)
|
|
EVT_MENU(LIST_DESELECT_ALL, MyFrame::OnDeselectAll)
|
|
EVT_MENU(LIST_SELECT_ALL, MyFrame::OnSelectAll)
|
|
EVT_MENU(LIST_DELETE, MyFrame::OnDelete)
|
|
EVT_MENU(LIST_ADD, MyFrame::OnAdd)
|
|
EVT_MENU(LIST_EDIT, MyFrame::OnEdit)
|
|
EVT_MENU(LIST_DELETE_ALL, MyFrame::OnDeleteAll)
|
|
EVT_MENU(LIST_SORT, MyFrame::OnSort)
|
|
EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour)
|
|
EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour)
|
|
EVT_MENU(LIST_ROW_LINES, MyFrame::OnSetRowLines)
|
|
EVT_MENU(LIST_CUSTOM_HEADER_ATTR, MyFrame::OnCustomHeaderAttr)
|
|
EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel)
|
|
EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo)
|
|
EVT_MENU(LIST_SHOW_SEL_INFO, MyFrame::OnShowSelInfo)
|
|
EVT_MENU(LIST_SHOW_VIEW_RECT, MyFrame::OnShowViewRect)
|
|
#ifdef wxHAS_LISTCTRL_COLUMN_ORDER
|
|
EVT_MENU(LIST_SET_COL_ORDER, MyFrame::OnSetColOrder)
|
|
EVT_MENU(LIST_GET_COL_ORDER, MyFrame::OnGetColOrder)
|
|
#endif // wxHAS_LISTCTRL_COLUMN_ORDER
|
|
EVT_MENU(LIST_FREEZE, MyFrame::OnFreeze)
|
|
EVT_MENU(LIST_THAW, MyFrame::OnThaw)
|
|
EVT_MENU(LIST_TOGGLE_LINES, MyFrame::OnToggleLines)
|
|
EVT_MENU(LIST_TOGGLE_HEADER, MyFrame::OnToggleHeader)
|
|
EVT_MENU(LIST_TOGGLE_BELL, MyFrame::OnToggleBell)
|
|
#ifdef __WXOSX__
|
|
EVT_MENU(LIST_MAC_USE_GENERIC, MyFrame::OnToggleMacUseGeneric)
|
|
#endif // __WXOSX__
|
|
EVT_MENU(LIST_FIND, MyFrame::OnFind)
|
|
EVT_MENU(LIST_TOGGLE_CHECKBOX, MyFrame::OnToggleItemCheckBox)
|
|
EVT_MENU(LIST_GET_CHECKBOX, MyFrame::OnGetItemCheckBox)
|
|
EVT_MENU(LIST_TOGGLE_CHECKBOXES, MyFrame::OnToggleCheckBoxes)
|
|
|
|
EVT_UPDATE_UI(LIST_SHOW_COL_INFO, MyFrame::OnUpdateUIEnableInReport)
|
|
EVT_UPDATE_UI(LIST_TOGGLE_HEADER, MyFrame::OnUpdateUIEnableInReport)
|
|
EVT_UPDATE_UI(LIST_CUSTOM_HEADER_ATTR, MyFrame::OnUpdateUIEnableInReport)
|
|
|
|
EVT_UPDATE_UI(LIST_TOGGLE_MULTI_SEL, MyFrame::OnUpdateToggleMultiSel)
|
|
EVT_UPDATE_UI(LIST_TOGGLE_CHECKBOXES, MyFrame::OnUpdateToggleCheckBoxes)
|
|
EVT_UPDATE_UI(LIST_TOGGLE_HEADER, MyFrame::OnUpdateToggleHeader)
|
|
EVT_UPDATE_UI(LIST_ROW_LINES, MyFrame::OnUpdateRowLines)
|
|
wxEND_EVENT_TABLE()
|
|
|
|
// My frame constructor
|
|
MyFrame::MyFrame(const wxChar *title)
|
|
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(600, 500))
|
|
{
|
|
m_listCtrl = NULL;
|
|
m_logWindow = NULL;
|
|
m_smallVirtual = false;
|
|
m_numListItems = 10;
|
|
|
|
// Give it an icon
|
|
SetIcon(wxICON(sample));
|
|
|
|
// Make an image list containing large icons
|
|
m_imageListNormal = new wxImageList(32, 32, true);
|
|
m_imageListSmall = new wxImageList(16, 16, true);
|
|
|
|
#ifdef wxHAS_IMAGES_IN_RESOURCES
|
|
m_imageListNormal->Add( wxIcon(wxT("icon1"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
m_imageListNormal->Add( wxIcon(wxT("icon2"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
m_imageListNormal->Add( wxIcon(wxT("icon3"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
m_imageListNormal->Add( wxIcon(wxT("icon4"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
m_imageListNormal->Add( wxIcon(wxT("icon5"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
m_imageListNormal->Add( wxIcon(wxT("icon6"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
m_imageListNormal->Add( wxIcon(wxT("icon7"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
m_imageListNormal->Add( wxIcon(wxT("icon8"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
m_imageListNormal->Add( wxIcon(wxT("icon9"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
|
|
m_imageListSmall->Add( wxIcon(wxT("iconsmall"), wxBITMAP_TYPE_ICO_RESOURCE) );
|
|
|
|
#else
|
|
m_imageListNormal->Add( wxIcon( toolbrai_xpm ) );
|
|
m_imageListNormal->Add( wxIcon( toolchar_xpm ) );
|
|
m_imageListNormal->Add( wxIcon( tooldata_xpm ) );
|
|
m_imageListNormal->Add( wxIcon( toolnote_xpm ) );
|
|
m_imageListNormal->Add( wxIcon( tooltodo_xpm ) );
|
|
m_imageListNormal->Add( wxIcon( toolchec_xpm ) );
|
|
m_imageListNormal->Add( wxIcon( toolgame_xpm ) );
|
|
m_imageListNormal->Add( wxIcon( tooltime_xpm ) );
|
|
m_imageListNormal->Add( wxIcon( toolword_xpm ) );
|
|
|
|
m_imageListSmall->Add( wxIcon( small1_xpm) );
|
|
#endif
|
|
|
|
// Make a menubar
|
|
wxMenu *menuFile = new wxMenu;
|
|
menuFile->Append(LIST_ABOUT, wxT("&About"));
|
|
menuFile->AppendSeparator();
|
|
menuFile->Append(LIST_QUIT, wxT("E&xit\tAlt-X"));
|
|
|
|
wxMenu *menuView = new wxMenu;
|
|
menuView->Append(LIST_LIST_VIEW, wxT("&List view\tF1"));
|
|
menuView->Append(LIST_REPORT_VIEW, wxT("&Report view\tF2"));
|
|
menuView->Append(LIST_ICON_VIEW, wxT("&Icon view\tF3"));
|
|
menuView->Append(LIST_ICON_TEXT_VIEW, wxT("Icon view with &text\tF4"));
|
|
menuView->Append(LIST_SMALL_ICON_VIEW, wxT("&Small icon view\tF5"));
|
|
menuView->Append(LIST_SMALL_ICON_TEXT_VIEW, wxT("Small icon &view with text\tF6"));
|
|
menuView->Append(LIST_VIRTUAL_VIEW, wxT("&Virtual view\tF7"));
|
|
menuView->Append(LIST_SMALL_VIRTUAL_VIEW, wxT("Small virtual vie&w\tF8"));
|
|
menuView->AppendSeparator();
|
|
menuView->Append(LIST_SET_ITEMS_COUNT, "Set &number of items");
|
|
#ifdef __WXOSX__
|
|
menuView->AppendSeparator();
|
|
menuView->AppendCheckItem(LIST_MAC_USE_GENERIC, wxT("Mac: Use Generic Control"));
|
|
#endif
|
|
|
|
wxMenu *menuList = new wxMenu;
|
|
menuList->Append(LIST_GOTO, wxT("&Go to item #3\tCtrl-3"));
|
|
menuList->Append(LIST_FOCUS_LAST, wxT("&Make last item current\tCtrl-L"));
|
|
menuList->Append(LIST_TOGGLE_FIRST, wxT("To&ggle first item\tCtrl-G"));
|
|
menuList->Append(LIST_DESELECT_ALL, wxT("&Deselect All\tCtrl-D"));
|
|
menuList->Append(LIST_SELECT_ALL, wxT("S&elect All\tCtrl-A"));
|
|
menuList->AppendSeparator();
|
|
menuList->Append(LIST_SHOW_COL_INFO, wxT("Show &column info\tCtrl-C"));
|
|
menuList->Append(LIST_SHOW_SEL_INFO, wxT("Show &selected items\tCtrl-S"));
|
|
menuList->Append(LIST_SHOW_VIEW_RECT, wxT("Show &view rect"));
|
|
#ifdef wxHAS_LISTCTRL_COLUMN_ORDER
|
|
menuList->Append(LIST_SET_COL_ORDER, wxT("Se&t columns order\tShift-Ctrl-O"));
|
|
menuList->Append(LIST_GET_COL_ORDER, wxT("Sho&w columns order\tCtrl-O"));
|
|
#endif // wxHAS_LISTCTRL_COLUMN_ORDER
|
|
menuList->AppendSeparator();
|
|
menuList->Append(LIST_SORT, wxT("Sor&t\tCtrl-T"));
|
|
menuList->Append(LIST_FIND, "Test Find() performance");
|
|
menuList->AppendSeparator();
|
|
menuList->Append(LIST_ADD, wxT("&Append an item\tCtrl-P"));
|
|
menuList->Append(LIST_EDIT, wxT("&Edit the item\tCtrl-E"));
|
|
menuList->Append(LIST_DELETE, wxT("&Delete first item\tCtrl-X"));
|
|
menuList->Append(LIST_DELETE_ALL, wxT("Delete &all items"));
|
|
menuList->AppendSeparator();
|
|
menuList->Append(LIST_FREEZE, wxT("Free&ze\tCtrl-Z"));
|
|
menuList->Append(LIST_THAW, wxT("Tha&w\tCtrl-W"));
|
|
menuList->AppendSeparator();
|
|
menuList->AppendCheckItem(LIST_TOGGLE_LINES, wxT("Toggle &lines\tCtrl-I"));
|
|
menuList->AppendCheckItem(LIST_TOGGLE_MULTI_SEL,
|
|
wxT("&Multiple selection\tCtrl-M"));
|
|
menuList->Check(LIST_TOGGLE_MULTI_SEL, true);
|
|
menuList->AppendCheckItem(LIST_TOGGLE_HEADER, "Toggle &header\tCtrl-H");
|
|
menuList->Check(LIST_TOGGLE_HEADER, true);
|
|
menuList->AppendCheckItem(LIST_TOGGLE_BELL, "Toggle &bell on no match");
|
|
menuList->AppendSeparator();
|
|
menuList->AppendCheckItem(LIST_TOGGLE_CHECKBOXES,
|
|
wxT("&Enable Checkboxes"));
|
|
menuList->Check(LIST_TOGGLE_CHECKBOXES, true);
|
|
menuList->Append(LIST_TOGGLE_CHECKBOX, wxT("Toggle the item checkbox state"));
|
|
menuList->Append(LIST_GET_CHECKBOX, wxT("Get the item checkbox state"));
|
|
|
|
wxMenu *menuCol = new wxMenu;
|
|
menuCol->Append(LIST_SET_FG_COL, wxT("&Foreground colour..."));
|
|
menuCol->Append(LIST_SET_BG_COL, wxT("&Background colour..."));
|
|
menuCol->AppendCheckItem(LIST_ROW_LINES, wxT("Alternating colours"));
|
|
menuCol->AppendCheckItem(LIST_CUSTOM_HEADER_ATTR, "&Custom header attributes");
|
|
|
|
wxMenuBar *menubar = new wxMenuBar;
|
|
menubar->Append(menuFile, wxT("&File"));
|
|
menubar->Append(menuView, wxT("&View"));
|
|
menubar->Append(menuList, wxT("&List"));
|
|
menubar->Append(menuCol, wxT("&Colour"));
|
|
SetMenuBar(menubar);
|
|
|
|
m_panel = new wxPanel(this, wxID_ANY);
|
|
m_logWindow = new wxTextCtrl(m_panel, wxID_ANY, wxEmptyString,
|
|
wxDefaultPosition, wxDefaultSize,
|
|
wxTE_READONLY | wxTE_MULTILINE | wxSUNKEN_BORDER);
|
|
|
|
m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_logWindow));
|
|
|
|
RecreateList(wxLC_REPORT | wxLC_SINGLE_SEL);
|
|
|
|
#ifdef __WXMSW__
|
|
// this is useful to know specially when debugging :)
|
|
wxLogMessage("Your version of comctl32.dll is: %d",
|
|
wxApp::GetComCtl32Version());
|
|
#endif
|
|
|
|
#if wxUSE_STATUSBAR
|
|
CreateStatusBar();
|
|
#endif // wxUSE_STATUSBAR
|
|
|
|
wxBoxSizer* const sizer = new wxBoxSizer(wxVERTICAL);
|
|
sizer->Add(m_listCtrl, wxSizerFlags(2).Expand().Border());
|
|
sizer->Add(m_logWindow, wxSizerFlags(1).Expand().Border());
|
|
m_panel->SetSizer(sizer);
|
|
|
|
SetClientSize(m_panel->GetBestSize());
|
|
}
|
|
|
|
MyFrame::~MyFrame()
|
|
{
|
|
delete wxLog::SetActiveTarget(m_logOld);
|
|
|
|
delete m_imageListNormal;
|
|
delete m_imageListSmall;
|
|
}
|
|
|
|
bool MyFrame::CheckNonVirtual() const
|
|
{
|
|
if ( !m_listCtrl->HasFlag(wxLC_VIRTUAL) )
|
|
return true;
|
|
|
|
// "this" == whatever
|
|
wxLogWarning(wxT("Can't do this in virtual view, sorry."));
|
|
|
|
return false;
|
|
}
|
|
|
|
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
Close(true);
|
|
}
|
|
|
|
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxMessageDialog dialog(this, wxT("List test sample\nJulian Smart (c) 1997"),
|
|
wxT("About list test"));
|
|
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MyFrame::OnFreeze(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxLogMessage(wxT("Freezing the control"));
|
|
|
|
m_listCtrl->Freeze();
|
|
}
|
|
|
|
void MyFrame::OnThaw(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxLogMessage(wxT("Thawing the control"));
|
|
|
|
m_listCtrl->Thaw();
|
|
}
|
|
|
|
void MyFrame::OnToggleLines(wxCommandEvent& event)
|
|
{
|
|
m_listCtrl->SetSingleStyle(wxLC_HRULES | wxLC_VRULES, event.IsChecked());
|
|
}
|
|
|
|
void MyFrame::OnToggleHeader(wxCommandEvent& event)
|
|
{
|
|
wxLogMessage("%s the header", event.IsChecked() ? "Showing" : "Hiding");
|
|
|
|
m_listCtrl->ToggleWindowStyle(wxLC_NO_HEADER);
|
|
}
|
|
|
|
void MyFrame::OnToggleBell(wxCommandEvent& event)
|
|
{
|
|
m_listCtrl->EnableBellOnNoMatch(event.IsChecked());
|
|
}
|
|
|
|
#ifdef __WXOSX__
|
|
|
|
void MyFrame::OnToggleMacUseGeneric(wxCommandEvent& event)
|
|
{
|
|
wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), event.IsChecked());
|
|
}
|
|
|
|
#endif // __WXOSX__
|
|
|
|
void MyFrame::OnGoTo(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
long index = 3;
|
|
m_listCtrl->SetItemState(index, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
|
|
|
|
long sel = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL,
|
|
wxLIST_STATE_SELECTED);
|
|
if ( sel != -1 )
|
|
m_listCtrl->SetItemState(sel, 0, wxLIST_STATE_SELECTED);
|
|
m_listCtrl->SetItemState(index, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
}
|
|
|
|
void MyFrame::OnFocusLast(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
long index = m_listCtrl->GetItemCount() - 1;
|
|
if ( index == -1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_listCtrl->SetItemState(index, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
|
|
m_listCtrl->EnsureVisible(index);
|
|
}
|
|
|
|
void MyFrame::OnToggleFirstSel(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_listCtrl->SetItemState(0, (~m_listCtrl->GetItemState(0, wxLIST_STATE_SELECTED) ) & wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
}
|
|
|
|
void MyFrame::OnDeselectAll(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
if ( !CheckNonVirtual() )
|
|
return;
|
|
|
|
int n = m_listCtrl->GetItemCount();
|
|
for (int i = 0; i < n; i++)
|
|
m_listCtrl->SetItemState(i,0,wxLIST_STATE_SELECTED);
|
|
}
|
|
|
|
void MyFrame::OnSelectAll(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
if ( !CheckNonVirtual() )
|
|
return;
|
|
|
|
int n = m_listCtrl->GetItemCount();
|
|
for (int i = 0; i < n; i++)
|
|
m_listCtrl->SetItemState(i,wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// changing listctrl modes
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void MyFrame::RecreateList(long flags, bool withText)
|
|
{
|
|
// we could avoid recreating it if we don't set/clear the wxLC_VIRTUAL
|
|
// style, but it is more trouble to do it than not
|
|
#if 0
|
|
if ( !m_listCtrl || ((flags & wxLC_VIRTUAL) !=
|
|
(m_listCtrl->GetWindowStyleFlag() & wxLC_VIRTUAL)) )
|
|
#endif
|
|
{
|
|
wxListCtrl* const old = m_listCtrl;
|
|
|
|
m_listCtrl = new MyListCtrl(m_panel, LIST_CTRL,
|
|
wxDefaultPosition, wxDefaultSize,
|
|
flags |
|
|
wxBORDER_THEME | wxLC_EDIT_LABELS);
|
|
|
|
if ( old )
|
|
{
|
|
wxSizer* const sizer = m_panel->GetSizer();
|
|
sizer->Replace(old, m_listCtrl);
|
|
|
|
delete old;
|
|
|
|
sizer->Layout();
|
|
}
|
|
|
|
switch ( flags & wxLC_MASK_TYPE )
|
|
{
|
|
case wxLC_LIST:
|
|
InitWithListItems();
|
|
break;
|
|
|
|
case wxLC_ICON:
|
|
InitWithIconItems(withText);
|
|
break;
|
|
|
|
case wxLC_SMALL_ICON:
|
|
InitWithIconItems(withText, true);
|
|
break;
|
|
|
|
case wxLC_REPORT:
|
|
if ( flags & wxLC_VIRTUAL )
|
|
InitWithVirtualItems();
|
|
else
|
|
InitWithReportItems();
|
|
break;
|
|
|
|
default:
|
|
wxFAIL_MSG( wxT("unknown listctrl mode") );
|
|
}
|
|
|
|
wxMenuBar* const mb = GetMenuBar();
|
|
if ( mb )
|
|
m_listCtrl->EnableBellOnNoMatch(mb->IsChecked(LIST_TOGGLE_BELL));
|
|
}
|
|
|
|
GetMenuBar()->Check(LIST_ROW_LINES, false);
|
|
|
|
m_logWindow->Clear();
|
|
}
|
|
|
|
void MyFrame::OnListView(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
RecreateList(wxLC_LIST);
|
|
}
|
|
|
|
void MyFrame::InitWithListItems()
|
|
{
|
|
for ( int i = 0; i < m_numListItems; i++ )
|
|
{
|
|
m_listCtrl->InsertItem(i, wxString::Format(wxT("Item %d"), i));
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnReportView(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
RecreateList(wxLC_REPORT);
|
|
}
|
|
|
|
void MyFrame::InitWithReportItems()
|
|
{
|
|
m_listCtrl->SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL);
|
|
|
|
// note that under MSW for SetColumnWidth() to work we need to create the
|
|
// items with images initially even if we specify dummy image id
|
|
wxListItem itemCol;
|
|
itemCol.SetText(wxT("Column 1"));
|
|
itemCol.SetImage(-1);
|
|
m_listCtrl->InsertColumn(0, itemCol);
|
|
|
|
itemCol.SetText(wxT("Column 2 (auto size excluding header)"));
|
|
itemCol.SetAlign(wxLIST_FORMAT_CENTRE);
|
|
m_listCtrl->InsertColumn(1, itemCol);
|
|
|
|
itemCol.SetText(wxT("Column 3 (auto size including header)"));
|
|
itemCol.SetAlign(wxLIST_FORMAT_RIGHT);
|
|
m_listCtrl->InsertColumn(2, itemCol);
|
|
|
|
// to speed up inserting we hide the control temporarily
|
|
m_listCtrl->Hide();
|
|
|
|
wxStopWatch sw;
|
|
|
|
for ( int i = 0; i < m_numListItems; i++ )
|
|
{
|
|
m_listCtrl->InsertItemInReportView(i);
|
|
}
|
|
|
|
m_logWindow->WriteText(wxString::Format(wxT("%d items inserted in %ldms\n"),
|
|
m_numListItems, sw.Time()));
|
|
m_listCtrl->Show();
|
|
|
|
// we leave all mask fields to 0 and only change the colour
|
|
wxListItem item;
|
|
item.m_itemId = 0;
|
|
item.SetTextColour(*wxRED);
|
|
m_listCtrl->SetItem( item );
|
|
|
|
item.m_itemId = 2;
|
|
item.SetTextColour(*wxGREEN);
|
|
m_listCtrl->SetItem( item );
|
|
item.m_itemId = 4;
|
|
item.SetTextColour(*wxLIGHT_GREY);
|
|
item.SetFont(*wxITALIC_FONT);
|
|
item.SetBackgroundColour(*wxRED);
|
|
m_listCtrl->SetItem( item );
|
|
|
|
m_listCtrl->SetTextColour(*wxBLUE);
|
|
|
|
// Set images in columns
|
|
m_listCtrl->SetItemColumnImage(1, 1, 0);
|
|
|
|
wxListItem info;
|
|
info.SetImage(0);
|
|
info.SetId(3);
|
|
info.SetColumn(2);
|
|
m_listCtrl->SetItem(info);
|
|
|
|
// test SetItemFont too
|
|
m_listCtrl->SetItemFont(0, *wxITALIC_FONT);
|
|
|
|
m_listCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
|
|
m_listCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
|
|
m_listCtrl->SetColumnWidth( 2, wxLIST_AUTOSIZE_USEHEADER );
|
|
}
|
|
|
|
void MyFrame::InitWithIconItems(bool withText, bool sameIcon)
|
|
{
|
|
m_listCtrl->SetImageList(m_imageListNormal, wxIMAGE_LIST_NORMAL);
|
|
m_listCtrl->SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL);
|
|
|
|
for ( int i = 0; i < NUM_ICONS; i++ )
|
|
{
|
|
int image = sameIcon ? 0 : i;
|
|
|
|
if ( withText )
|
|
{
|
|
// Make labels of different widths to test the layout.
|
|
wxString label;
|
|
if ( !(i % 5) )
|
|
label.Printf("Longer label %d", i);
|
|
else
|
|
label.Printf("Label %d", i);
|
|
|
|
m_listCtrl->InsertItem(i, label, image);
|
|
}
|
|
else
|
|
{
|
|
m_listCtrl->InsertItem(i, image);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnIconView(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
RecreateList(wxLC_ICON, false);
|
|
}
|
|
|
|
void MyFrame::OnIconTextView(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
RecreateList(wxLC_ICON);
|
|
}
|
|
|
|
void MyFrame::OnSmallIconView(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
RecreateList(wxLC_SMALL_ICON, false);
|
|
}
|
|
|
|
void MyFrame::OnSmallIconTextView(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
RecreateList(wxLC_SMALL_ICON);
|
|
}
|
|
|
|
void MyFrame::OnVirtualView(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_smallVirtual = false;
|
|
RecreateList(wxLC_REPORT | wxLC_VIRTUAL);
|
|
}
|
|
|
|
void MyFrame::OnSmallVirtualView(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_smallVirtual = true;
|
|
RecreateList(wxLC_REPORT | wxLC_VIRTUAL);
|
|
}
|
|
|
|
void MyFrame::OnSetItemsCount(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
int numItems = wxGetNumberFromUser
|
|
(
|
|
"Enter the initial number of items for "
|
|
"the list and report views",
|
|
"Number of items:",
|
|
"wxWidgets wxListCtrl sample",
|
|
m_numListItems,
|
|
0,
|
|
10000,
|
|
this
|
|
);
|
|
if ( numItems == -1 || numItems == m_numListItems )
|
|
return;
|
|
|
|
m_numListItems = numItems;
|
|
|
|
if ( m_listCtrl->HasFlag(wxLC_REPORT) &&
|
|
!m_listCtrl->HasFlag(wxLC_VIRTUAL) )
|
|
RecreateList(wxLC_REPORT);
|
|
else if ( m_listCtrl->HasFlag(wxLC_LIST) )
|
|
RecreateList(wxLC_LIST);
|
|
}
|
|
|
|
void MyFrame::InitWithVirtualItems()
|
|
{
|
|
m_listCtrl->SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL);
|
|
|
|
if ( m_smallVirtual )
|
|
{
|
|
m_listCtrl->AppendColumn(wxT("Animal"));
|
|
m_listCtrl->AppendColumn(wxT("Sound"));
|
|
m_listCtrl->SetItemCount(WXSIZEOF(SMALL_VIRTUAL_VIEW_ITEMS));
|
|
}
|
|
else
|
|
{
|
|
m_listCtrl->AppendColumn(wxT("First Column (size auto)"));
|
|
m_listCtrl->AppendColumn(wxT("Second Column (150px)"));
|
|
m_listCtrl->SetItemCount(1000000);
|
|
m_listCtrl->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
|
|
m_listCtrl->SetColumnWidth(1, 150);
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnSort(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxStopWatch sw;
|
|
|
|
m_listCtrl->SortItems(MyCompareFunction, 0);
|
|
|
|
m_logWindow->WriteText(wxString::Format(wxT("Sorting %d items took %ld ms\n"),
|
|
m_listCtrl->GetItemCount(),
|
|
sw.Time()));
|
|
}
|
|
|
|
void MyFrame::OnFind(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxStopWatch sw;
|
|
|
|
const int itemCount = m_listCtrl->GetItemCount();
|
|
for ( int i = 0; i < itemCount; i++ )
|
|
m_listCtrl->FindItem(-1, i);
|
|
|
|
wxLogMessage("Calling Find() for all %d items took %ld ms",
|
|
itemCount, sw.Time());
|
|
}
|
|
|
|
void MyFrame::OnShowSelInfo(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
int selCount = m_listCtrl->GetSelectedItemCount();
|
|
wxLogMessage(wxT("%d items selected:"), selCount);
|
|
|
|
// don't show too many items
|
|
size_t shownCount = 0;
|
|
|
|
long item = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL,
|
|
wxLIST_STATE_SELECTED);
|
|
while ( item != -1 )
|
|
{
|
|
wxLogMessage(wxT("\t%ld (%s)"),
|
|
item, m_listCtrl->GetItemText(item).c_str());
|
|
|
|
if ( ++shownCount > 10 )
|
|
{
|
|
wxLogMessage(wxT("\t... more selected items snipped..."));
|
|
break;
|
|
}
|
|
|
|
item = m_listCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
|
|
wxLIST_STATE_SELECTED);
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnShowViewRect(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
const wxRect r = m_listCtrl->GetViewRect();
|
|
wxLogMessage("View rect: (%d, %d)-(%d, %d)",
|
|
r.GetLeft(), r.GetTop(), r.GetRight(), r.GetBottom());
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// column order tests
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#ifdef wxHAS_LISTCTRL_COLUMN_ORDER
|
|
|
|
static wxString DumpIntArray(const wxArrayInt& a)
|
|
{
|
|
wxString s("{ ");
|
|
const size_t count = a.size();
|
|
for ( size_t n = 0; n < count; n++ )
|
|
{
|
|
if ( n )
|
|
s += ", ";
|
|
s += wxString::Format("%lu", (unsigned long)a[n]);
|
|
}
|
|
|
|
s += " }";
|
|
|
|
return s;
|
|
}
|
|
|
|
void MyFrame::OnSetColOrder(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxArrayInt order(3);
|
|
order[0] = 2;
|
|
order[1] = 0;
|
|
order[2] = 1;
|
|
if ( m_listCtrl->SetColumnsOrder(order) )
|
|
{
|
|
wxLogMessage("Column order set to %s", DumpIntArray(order));
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnGetColOrder(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
// show what GetColumnsOrder() returns
|
|
const wxArrayInt order = m_listCtrl->GetColumnsOrder();
|
|
wxString msg = "Columns order: " +
|
|
DumpIntArray(m_listCtrl->GetColumnsOrder()) + "\n";
|
|
|
|
int n;
|
|
const int count = m_listCtrl->GetColumnCount();
|
|
|
|
// show the results of GetColumnOrder() for each column
|
|
msg += "GetColumnOrder() results:\n";
|
|
for ( n = 0; n < count; n++ )
|
|
{
|
|
msg += wxString::Format(" %2d -> %2d\n",
|
|
n, m_listCtrl->GetColumnOrder(n));
|
|
}
|
|
|
|
// and the results of GetColumnIndexFromOrder() too
|
|
msg += "GetColumnIndexFromOrder() results:\n";
|
|
for ( n = 0; n < count; n++ )
|
|
{
|
|
msg += wxString::Format(" %2d -> %2d\n",
|
|
n, m_listCtrl->GetColumnIndexFromOrder(n));
|
|
}
|
|
|
|
wxLogMessage("%s", msg);
|
|
}
|
|
|
|
#endif // wxHAS_LISTCTRL_COLUMN_ORDER
|
|
|
|
void MyFrame::OnShowColInfo(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
int count = m_listCtrl->GetColumnCount();
|
|
wxLogMessage(wxT("%d columns:"), count);
|
|
for ( int c = 0; c < count; c++ )
|
|
{
|
|
wxLogMessage(wxT("\tcolumn %d has width %d"), c,
|
|
m_listCtrl->GetColumnWidth(c));
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnUpdateUIEnableInReport(wxUpdateUIEvent& event)
|
|
{
|
|
event.Enable( (m_listCtrl->GetWindowStyleFlag() & wxLC_REPORT) != 0 );
|
|
}
|
|
|
|
void MyFrame::OnToggleMultiSel(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
long flags = m_listCtrl->GetWindowStyleFlag();
|
|
if ( flags & wxLC_SINGLE_SEL )
|
|
flags &= ~wxLC_SINGLE_SEL;
|
|
else
|
|
flags |= wxLC_SINGLE_SEL;
|
|
|
|
m_logWindow->WriteText(wxString::Format(wxT("Current selection mode: %sle\n"),
|
|
(flags & wxLC_SINGLE_SEL) ? wxT("sing") : wxT("multip")));
|
|
|
|
RecreateList(flags);
|
|
}
|
|
|
|
void MyFrame::OnUpdateToggleMultiSel(wxUpdateUIEvent& event)
|
|
{
|
|
event.Check(!m_listCtrl->HasFlag(wxLC_SINGLE_SEL));
|
|
}
|
|
|
|
void MyFrame::OnToggleCheckBoxes(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
if ( !m_listCtrl->EnableCheckBoxes(!m_listCtrl->HasCheckBoxes()) )
|
|
{
|
|
wxLogMessage("Failed to toggle checkboxes (not supported?)");
|
|
}
|
|
else
|
|
{
|
|
wxLogMessage("Checkboxes are now %s",
|
|
m_listCtrl->HasCheckBoxes() ? "enabled" : "disabled");
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnUpdateToggleCheckBoxes(wxUpdateUIEvent& event)
|
|
{
|
|
bool cbEnabled = m_listCtrl->HasCheckBoxes();
|
|
event.Check(cbEnabled);
|
|
GetMenuBar()->Enable(LIST_TOGGLE_CHECKBOX, cbEnabled);
|
|
GetMenuBar()->Enable(LIST_GET_CHECKBOX, cbEnabled);
|
|
}
|
|
|
|
void MyFrame::OnUpdateToggleHeader(wxUpdateUIEvent& event)
|
|
{
|
|
event.Check(!m_listCtrl->HasFlag(wxLC_NO_HEADER));
|
|
}
|
|
|
|
void MyFrame::OnUpdateRowLines(wxUpdateUIEvent& event)
|
|
{
|
|
event.Enable(m_listCtrl->HasFlag(wxLC_VIRTUAL));
|
|
}
|
|
|
|
void MyFrame::OnSetFgColour(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_listCtrl->SetForegroundColour(wxGetColourFromUser(this));
|
|
m_listCtrl->Refresh();
|
|
}
|
|
|
|
void MyFrame::OnSetBgColour(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_listCtrl->SetBackgroundColour(wxGetColourFromUser(this));
|
|
m_listCtrl->Refresh();
|
|
}
|
|
|
|
void MyFrame::OnSetRowLines(wxCommandEvent& event)
|
|
{
|
|
m_listCtrl->EnableAlternateRowColours(event.IsChecked());
|
|
m_listCtrl->Refresh();
|
|
}
|
|
|
|
void MyFrame::OnCustomHeaderAttr(wxCommandEvent& event)
|
|
{
|
|
wxItemAttr attr;
|
|
if ( event.IsChecked() )
|
|
{
|
|
attr.SetTextColour(*wxBLUE);
|
|
attr.SetFont(wxFontInfo(24).Italic());
|
|
}
|
|
//else: leave it as default to disable custom header attributes
|
|
|
|
if ( !m_listCtrl->SetHeaderAttr(attr) )
|
|
wxLogMessage("Sorry, header attributes not supported on this platform");
|
|
}
|
|
|
|
void MyFrame::OnAdd(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_listCtrl->InsertItem(m_listCtrl->GetItemCount(), wxT("Appended item"));
|
|
}
|
|
|
|
void MyFrame::OnEdit(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
// demonstrate cancelling editing: this currently is wxMSW-only
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
if ( m_listCtrl->GetEditControl() )
|
|
{
|
|
m_listCtrl->EndEditLabel(true);
|
|
}
|
|
else // start editing
|
|
#endif // __WXMSW__
|
|
{
|
|
long itemCur = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL,
|
|
wxLIST_STATE_FOCUSED);
|
|
|
|
if ( itemCur != -1 )
|
|
{
|
|
m_listCtrl->EditLabel(itemCur);
|
|
}
|
|
else
|
|
{
|
|
m_logWindow->WriteText(wxT("No item to edit"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnToggleItemCheckBox(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
long item = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
|
while (item != -1)
|
|
{
|
|
bool checked = m_listCtrl->IsItemChecked(item);
|
|
m_listCtrl->CheckItem(item, !checked);
|
|
|
|
item = m_listCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
|
|
wxLIST_STATE_SELECTED);
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnGetItemCheckBox(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
long item = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
|
while (item != -1)
|
|
{
|
|
bool checked = m_listCtrl->IsItemChecked(item);
|
|
|
|
wxLogMessage(wxT("Item %ld is %s"), item, checked ? wxT("checked") : wxT("unchecked"));
|
|
|
|
item = m_listCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
|
|
wxLIST_STATE_SELECTED);
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
if ( m_listCtrl->GetItemCount() )
|
|
{
|
|
m_listCtrl->DeleteItem(0);
|
|
}
|
|
else
|
|
{
|
|
m_logWindow->WriteText(wxT("Nothing to delete"));
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnDeleteAll(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxStopWatch sw;
|
|
|
|
int itemCount = m_listCtrl->GetItemCount();
|
|
|
|
m_listCtrl->DeleteAllItems();
|
|
|
|
m_logWindow->WriteText(wxString::Format(wxT("Deleting %d items took %ld ms\n"),
|
|
itemCount,
|
|
sw.Time()));
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// MyListCtrl
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxBEGIN_EVENT_TABLE(MyListCtrl, wxListCtrl)
|
|
EVT_LIST_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnBeginDrag)
|
|
EVT_LIST_BEGIN_RDRAG(LIST_CTRL, MyListCtrl::OnBeginRDrag)
|
|
EVT_LIST_BEGIN_LABEL_EDIT(LIST_CTRL, MyListCtrl::OnBeginLabelEdit)
|
|
EVT_LIST_END_LABEL_EDIT(LIST_CTRL, MyListCtrl::OnEndLabelEdit)
|
|
EVT_LIST_DELETE_ITEM(LIST_CTRL, MyListCtrl::OnDeleteItem)
|
|
EVT_LIST_DELETE_ALL_ITEMS(LIST_CTRL, MyListCtrl::OnDeleteAllItems)
|
|
EVT_LIST_ITEM_SELECTED(LIST_CTRL, MyListCtrl::OnSelected)
|
|
EVT_LIST_ITEM_DESELECTED(LIST_CTRL, MyListCtrl::OnDeselected)
|
|
EVT_LIST_KEY_DOWN(LIST_CTRL, MyListCtrl::OnListKeyDown)
|
|
EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, MyListCtrl::OnActivated)
|
|
EVT_LIST_ITEM_FOCUSED(LIST_CTRL, MyListCtrl::OnFocused)
|
|
EVT_LIST_ITEM_CHECKED(LIST_CTRL, MyListCtrl::OnChecked)
|
|
EVT_LIST_ITEM_UNCHECKED(LIST_CTRL, MyListCtrl::OnUnChecked)
|
|
|
|
EVT_LIST_ITEM_RIGHT_CLICK(LIST_CTRL, MyListCtrl::OnItemRightClick)
|
|
|
|
EVT_LIST_COL_CLICK(LIST_CTRL, MyListCtrl::OnColClick)
|
|
EVT_LIST_COL_RIGHT_CLICK(LIST_CTRL, MyListCtrl::OnColRightClick)
|
|
EVT_LIST_COL_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnColBeginDrag)
|
|
EVT_LIST_COL_DRAGGING(LIST_CTRL, MyListCtrl::OnColDragging)
|
|
EVT_LIST_COL_END_DRAG(LIST_CTRL, MyListCtrl::OnColEndDrag)
|
|
|
|
EVT_LIST_CACHE_HINT(LIST_CTRL, MyListCtrl::OnCacheHint)
|
|
|
|
#if USE_CONTEXT_MENU
|
|
EVT_CONTEXT_MENU(MyListCtrl::OnContextMenu)
|
|
#endif
|
|
EVT_CHAR(MyListCtrl::OnChar)
|
|
|
|
EVT_RIGHT_DOWN(MyListCtrl::OnRightClick)
|
|
wxEND_EVENT_TABLE()
|
|
|
|
void MyListCtrl::OnCacheHint(wxListEvent& event)
|
|
{
|
|
wxLogMessage( wxT("OnCacheHint: cache items %ld..%ld"),
|
|
event.GetCacheFrom(), event.GetCacheTo() );
|
|
}
|
|
|
|
void MyListCtrl::SetColumnImage(int col, int image)
|
|
{
|
|
wxListItem item;
|
|
item.SetMask(wxLIST_MASK_IMAGE);
|
|
item.SetImage(image);
|
|
SetColumn(col, item);
|
|
}
|
|
|
|
void MyListCtrl::OnColClick(wxListEvent& event)
|
|
{
|
|
int col = event.GetColumn();
|
|
|
|
// set or unset image
|
|
static bool x = false;
|
|
x = !x;
|
|
SetColumnImage(col, x ? 0 : -1);
|
|
|
|
wxLogMessage( wxT("OnColumnClick at %d."), col );
|
|
}
|
|
|
|
void MyListCtrl::OnColRightClick(wxListEvent& event)
|
|
{
|
|
int col = event.GetColumn();
|
|
if ( col != -1 )
|
|
{
|
|
SetColumnImage(col, -1);
|
|
}
|
|
|
|
// Show popupmenu at position
|
|
wxMenu menu(wxT("Test"));
|
|
menu.Append(LIST_ABOUT, wxT("&About"));
|
|
PopupMenu(&menu, event.GetPoint());
|
|
|
|
wxLogMessage( wxT("OnColumnRightClick at %d."), event.GetColumn() );
|
|
}
|
|
|
|
void MyListCtrl::LogColEvent(const wxListEvent& event, const wxChar *name)
|
|
{
|
|
const int col = event.GetColumn();
|
|
|
|
wxLogMessage(wxT("%s: column %d (width = %d or %d)."),
|
|
name,
|
|
col,
|
|
event.GetItem().GetWidth(),
|
|
GetColumnWidth(col));
|
|
}
|
|
|
|
void MyListCtrl::OnColBeginDrag(wxListEvent& event)
|
|
{
|
|
LogColEvent( event, wxT("OnColBeginDrag") );
|
|
|
|
if ( event.GetColumn() == 0 )
|
|
{
|
|
wxLogMessage(wxT("Resizing this column shouldn't work."));
|
|
|
|
event.Veto();
|
|
}
|
|
}
|
|
|
|
void MyListCtrl::OnColDragging(wxListEvent& event)
|
|
{
|
|
LogColEvent( event, wxT("OnColDragging") );
|
|
}
|
|
|
|
void MyListCtrl::OnColEndDrag(wxListEvent& event)
|
|
{
|
|
LogColEvent( event, wxT("OnColEndDrag") );
|
|
}
|
|
|
|
void MyListCtrl::OnBeginDrag(wxListEvent& event)
|
|
{
|
|
const wxPoint& pt = event.m_pointDrag;
|
|
|
|
int flags;
|
|
wxLogMessage( wxT("OnBeginDrag at (%d, %d), item %ld."),
|
|
pt.x, pt.y, HitTest(pt, flags) );
|
|
}
|
|
|
|
void MyListCtrl::OnBeginRDrag(wxListEvent& event)
|
|
{
|
|
wxLogMessage( wxT("OnBeginRDrag at %d,%d."),
|
|
event.m_pointDrag.x, event.m_pointDrag.y );
|
|
}
|
|
|
|
void MyListCtrl::OnBeginLabelEdit(wxListEvent& event)
|
|
{
|
|
wxLogMessage( wxT("OnBeginLabelEdit: %s"), event.m_item.m_text.c_str());
|
|
|
|
wxTextCtrl * const text = GetEditControl();
|
|
if ( !text )
|
|
{
|
|
wxLogMessage("BUG: started to edit but no edit control");
|
|
}
|
|
else
|
|
{
|
|
wxLogMessage("Edit control value: \"%s\"", text->GetValue());
|
|
}
|
|
}
|
|
|
|
void MyListCtrl::OnEndLabelEdit(wxListEvent& event)
|
|
{
|
|
wxLogMessage( wxT("OnEndLabelEdit: %s"),
|
|
(
|
|
event.IsEditCancelled() ?
|
|
wxString("[cancelled]") :
|
|
event.m_item.m_text
|
|
).c_str()
|
|
);
|
|
}
|
|
|
|
void MyListCtrl::OnDeleteItem(wxListEvent& event)
|
|
{
|
|
LogEvent(event, wxT("OnDeleteItem"));
|
|
wxLogMessage( wxT("Number of items when delete event is sent: %d"), GetItemCount() );
|
|
}
|
|
|
|
void MyListCtrl::OnDeleteAllItems(wxListEvent& event)
|
|
{
|
|
LogEvent(event, wxT("OnDeleteAllItems"));
|
|
}
|
|
|
|
void MyListCtrl::OnSelected(wxListEvent& event)
|
|
{
|
|
LogEvent(event, wxT("OnSelected"));
|
|
|
|
if ( GetWindowStyle() & wxLC_REPORT )
|
|
{
|
|
wxListItem info;
|
|
info.m_itemId = event.m_itemIndex;
|
|
info.m_col = 1;
|
|
info.m_mask = wxLIST_MASK_TEXT;
|
|
if ( GetItem(info) )
|
|
{
|
|
wxLogMessage(wxT("Value of the 2nd field of the selected item: %s"),
|
|
info.m_text.c_str());
|
|
}
|
|
else
|
|
{
|
|
wxFAIL_MSG(wxT("wxListCtrl::GetItem() failed"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void MyListCtrl::OnDeselected(wxListEvent& event)
|
|
{
|
|
LogEvent(event, wxT("OnDeselected"));
|
|
}
|
|
|
|
void MyListCtrl::OnActivated(wxListEvent& event)
|
|
{
|
|
LogEvent(event, wxT("OnActivated"));
|
|
}
|
|
|
|
void MyListCtrl::OnFocused(wxListEvent& event)
|
|
{
|
|
LogEvent(event, wxT("OnFocused"));
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
void MyListCtrl::OnItemRightClick(wxListEvent& event)
|
|
{
|
|
LogEvent(event, wxT("OnItemRightClick"));
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
void MyListCtrl::OnChecked(wxListEvent& event)
|
|
{
|
|
LogEvent(event, wxT("OnChecked"));
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
void MyListCtrl::OnUnChecked(wxListEvent& event)
|
|
{
|
|
LogEvent(event, wxT("OnUnChecked"));
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
void MyListCtrl::OnListKeyDown(wxListEvent& event)
|
|
{
|
|
long item;
|
|
|
|
if ( !wxGetKeyState(WXK_SHIFT) )
|
|
{
|
|
LogEvent(event, wxT("OnListKeyDown"));
|
|
event.Skip();
|
|
return;
|
|
}
|
|
|
|
switch ( event.GetKeyCode() )
|
|
{
|
|
case 'C': // colorize
|
|
{
|
|
wxListItem info;
|
|
info.m_itemId = event.GetIndex();
|
|
if ( info.m_itemId == -1 )
|
|
{
|
|
// no item
|
|
break;
|
|
}
|
|
|
|
GetItem(info);
|
|
|
|
wxItemAttr *attr = info.GetAttributes();
|
|
if ( !attr || !attr->HasTextColour() )
|
|
{
|
|
info.SetTextColour(*wxCYAN);
|
|
|
|
SetItem(info);
|
|
|
|
RefreshItem(info.m_itemId);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'N': // next
|
|
item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED);
|
|
if ( item++ == GetItemCount() - 1 )
|
|
{
|
|
item = 0;
|
|
}
|
|
|
|
wxLogMessage(wxT("Focusing item %ld"), item);
|
|
|
|
SetItemState(item, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
|
|
EnsureVisible(item);
|
|
break;
|
|
|
|
case 'R': // show bounding rectangle
|
|
{
|
|
item = event.GetIndex();
|
|
wxRect r;
|
|
if ( !GetItemRect(item, r) )
|
|
{
|
|
wxLogError(wxT("Failed to retrieve rect of item %ld"), item);
|
|
break;
|
|
}
|
|
|
|
wxLogMessage(wxT("Bounding rect of item %ld is (%d, %d)-(%d, %d)"),
|
|
item, r.x, r.y, r.x + r.width, r.y + r.height);
|
|
}
|
|
break;
|
|
|
|
case '1': // show sub item bounding rectangle for the given column
|
|
case '2': // (and icon/label rectangle if Shift/Ctrl is pressed)
|
|
case '3':
|
|
case '4': // this column is invalid but we want to test it too
|
|
if ( InReportView() )
|
|
{
|
|
int subItem = event.GetKeyCode() - '1';
|
|
item = event.GetIndex();
|
|
wxRect r;
|
|
|
|
int code = wxLIST_RECT_BOUNDS;
|
|
if ( wxGetKeyState(WXK_SHIFT) )
|
|
code = wxLIST_RECT_ICON;
|
|
else if ( wxGetKeyState(WXK_CONTROL) )
|
|
code = wxLIST_RECT_LABEL;
|
|
|
|
if ( !GetSubItemRect(item, subItem, r, code) )
|
|
{
|
|
wxLogError(wxT("Failed to retrieve rect of item %ld column %d"), item, subItem + 1);
|
|
break;
|
|
}
|
|
|
|
wxLogMessage(wxT("Bounding rect of item %ld column %d is (%d, %d)-(%d, %d)"),
|
|
item, subItem + 1,
|
|
r.x, r.y, r.x + r.width, r.y + r.height);
|
|
}
|
|
break;
|
|
|
|
case 'U': // update
|
|
if ( !IsVirtual() )
|
|
break;
|
|
|
|
if ( m_updated != -1 )
|
|
RefreshItem(m_updated);
|
|
|
|
m_updated = event.GetIndex();
|
|
if ( m_updated != -1 )
|
|
{
|
|
// we won't see changes to this item as it's selected, update
|
|
// the next one (or the first one if we're on the last item)
|
|
if ( ++m_updated == GetItemCount() )
|
|
m_updated = 0;
|
|
|
|
wxLogMessage("Updating colour of the item %ld", m_updated);
|
|
RefreshItem(m_updated);
|
|
}
|
|
break;
|
|
|
|
case 'D': // delete
|
|
item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
|
while ( item != -1 )
|
|
{
|
|
DeleteItem(item);
|
|
|
|
wxLogMessage(wxT("Item %ld deleted"), item);
|
|
|
|
// -1 because the indices were shifted by DeleteItem()
|
|
item = GetNextItem(item - 1,
|
|
wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
|
}
|
|
break;
|
|
|
|
case 'I': // insert
|
|
if ( GetWindowStyle() & wxLC_REPORT )
|
|
{
|
|
if ( GetWindowStyle() & wxLC_VIRTUAL )
|
|
{
|
|
SetItemCount(GetItemCount() + 1);
|
|
}
|
|
else // !virtual
|
|
{
|
|
InsertItemInReportView(event.GetIndex());
|
|
}
|
|
break;
|
|
}
|
|
wxFALLTHROUGH;
|
|
|
|
default:
|
|
LogEvent(event, wxT("OnListKeyDown"));
|
|
|
|
event.Skip();
|
|
}
|
|
}
|
|
|
|
void MyListCtrl::OnChar(wxKeyEvent& event)
|
|
{
|
|
wxLogMessage(wxT("Got char event."));
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
void MyListCtrl::OnRightClick(wxMouseEvent& event)
|
|
{
|
|
if ( !event.ControlDown() )
|
|
{
|
|
event.Skip();
|
|
return;
|
|
}
|
|
|
|
int flags;
|
|
long subitem;
|
|
long item = HitTest(event.GetPosition(), flags, &subitem);
|
|
|
|
wxString where;
|
|
switch ( flags )
|
|
{
|
|
case wxLIST_HITTEST_ABOVE: where = wxT("above"); break;
|
|
case wxLIST_HITTEST_BELOW: where = wxT("below"); break;
|
|
case wxLIST_HITTEST_NOWHERE: where = wxT("nowhere near"); break;
|
|
case wxLIST_HITTEST_ONITEMICON: where = wxT("on icon of"); break;
|
|
case wxLIST_HITTEST_ONITEMLABEL: where = wxT("on label of"); break;
|
|
case wxLIST_HITTEST_ONITEMRIGHT: where = wxT("right on"); break;
|
|
case wxLIST_HITTEST_TOLEFT: where = wxT("to the left of"); break;
|
|
case wxLIST_HITTEST_TORIGHT: where = wxT("to the right of"); break;
|
|
default: where = wxT("not clear exactly where on"); break;
|
|
}
|
|
|
|
wxLogMessage(wxT("Right double click %s item %ld, subitem %ld"),
|
|
where.c_str(), item, subitem);
|
|
}
|
|
|
|
void MyListCtrl::LogEvent(const wxListEvent& event, const wxChar *eventName)
|
|
{
|
|
wxLogMessage(wxT("Item %ld: %s (item text = %s, data = %ld)"),
|
|
event.GetIndex(), eventName,
|
|
event.GetText(), static_cast<long>(event.GetData()));
|
|
}
|
|
|
|
wxString MyListCtrl::OnGetItemText(long item, long column) const
|
|
{
|
|
if ( GetItemCount() == WXSIZEOF(SMALL_VIRTUAL_VIEW_ITEMS) )
|
|
{
|
|
return SMALL_VIRTUAL_VIEW_ITEMS[item][column];
|
|
}
|
|
else // "big" virtual control
|
|
{
|
|
return wxString::Format(wxT("Column %ld of item %ld"), column, item);
|
|
}
|
|
}
|
|
|
|
int MyListCtrl::OnGetItemColumnImage(long item, long column) const
|
|
{
|
|
if (!column)
|
|
return 0;
|
|
|
|
if (!(item % 3) && column == 1)
|
|
return 0;
|
|
|
|
return -1;
|
|
}
|
|
|
|
wxItemAttr *MyListCtrl::OnGetItemAttr(long item) const
|
|
{
|
|
// test to check that RefreshItem() works correctly: when m_updated is
|
|
// set to some item and it is refreshed, we highlight the item
|
|
if ( item == m_updated )
|
|
{
|
|
static wxItemAttr s_attrHighlight(*wxRED, wxNullColour, wxNullFont);
|
|
return &s_attrHighlight;
|
|
}
|
|
|
|
return wxListCtrl::OnGetItemAttr(item);
|
|
}
|
|
|
|
void MyListCtrl::InsertItemInReportView(int i)
|
|
{
|
|
wxString buf;
|
|
buf.Printf(wxT("This is item %d"), i);
|
|
long tmp = InsertItem(i, buf, 0);
|
|
SetItemData(tmp, i);
|
|
|
|
buf.Printf(wxT("Col 1, item %d"), i);
|
|
SetItem(tmp, 1, buf);
|
|
|
|
buf.Printf(wxT("Item %d in column 2"), i);
|
|
SetItem(tmp, 2, buf);
|
|
}
|
|
|
|
#if USE_CONTEXT_MENU
|
|
void MyListCtrl::OnContextMenu(wxContextMenuEvent& event)
|
|
{
|
|
if (GetEditControl() == NULL)
|
|
{
|
|
wxPoint point = event.GetPosition();
|
|
// If from keyboard
|
|
if ( (point.x == -1) && (point.y == -1) )
|
|
{
|
|
wxSize size = GetSize();
|
|
point.x = size.x / 2;
|
|
point.y = size.y / 2;
|
|
}
|
|
else
|
|
{
|
|
point = ScreenToClient(point);
|
|
}
|
|
ShowContextMenu(point);
|
|
}
|
|
else
|
|
{
|
|
// the user is editing:
|
|
// allow the text control to display its context menu
|
|
// if it has one (it has on Windows) rather than display our one
|
|
event.Skip();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void MyListCtrl::ShowContextMenu(const wxPoint& pos)
|
|
{
|
|
wxMenu menu;
|
|
|
|
menu.Append(wxID_ABOUT, wxT("&About"));
|
|
menu.AppendSeparator();
|
|
menu.Append(wxID_EXIT, wxT("E&xit"));
|
|
|
|
PopupMenu(&menu, pos.x, pos.y);
|
|
}
|