#define wxTR_MAC_BUTTONS 0x0200
#define wxTR_ROW_LINES 0x0400
-/*
- * wxListCtrl flags
- */
-#define wxLC_VRULES 0x0001
-#define wxLC_HRULES 0x0002
-#define wxLC_ICON 0x0004
-#define wxLC_SMALL_ICON 0x0008
-#define wxLC_LIST 0x0010
-#define wxLC_REPORT 0x0020
-#define wxLC_ALIGN_TOP 0x0040
-#define wxLC_ALIGN_LEFT 0x0080
-#define wxLC_AUTOARRANGE 0x0100
-#define wxLC_USER_TEXT 0x0200
-#define wxLC_EDIT_LABELS 0x0400
-#define wxLC_NO_HEADER 0x0800
-#define wxLC_NO_SORT_HEADER 0x1000
-#define wxLC_SINGLE_SEL 0x2000
-#define wxLC_SORT_ASCENDING 0x4000
-#define wxLC_SORT_DESCENDING 0x8000
-
-#define wxLC_MASK_TYPE (wxLC_ICON | wxLC_SMALL_ICON | wxLC_LIST | wxLC_REPORT)
-#define wxLC_MASK_ALIGN (wxLC_ALIGN_TOP | wxLC_ALIGN_LEFT)
-#define wxLC_MASK_SORT (wxLC_SORT_ASCENDING | wxLC_SORT_DESCENDING)
-
-// Omitted because (a) too much detail (b) not enough style flags
-// #define wxLC_NO_SCROLL
-// #define wxLC_NO_LABEL_WRAP
-// #define wxLC_OWNERDRAW_FIXED
-// #define wxLC_SHOW_SEL_ALWAYS
-
/*
* wxSpinButton flags.
* Note that a wxSpinCtrl is sometimes defined as
// wxListCtrl constants
// ----------------------------------------------------------------------------
+// style flags
+#define wxLC_VRULES 0x0001
+#define wxLC_HRULES 0x0002
+#define wxLC_ICON 0x0004
+#define wxLC_SMALL_ICON 0x0008
+#define wxLC_LIST 0x0010
+#define wxLC_REPORT 0x0020
+#define wxLC_ALIGN_TOP 0x0040
+#define wxLC_ALIGN_LEFT 0x0080
+#define wxLC_AUTOARRANGE 0x0100
+#define wxLC_VIRTUAL 0x0200
+#define wxLC_EDIT_LABELS 0x0400
+#define wxLC_NO_HEADER 0x0800
+#define wxLC_NO_SORT_HEADER 0x1000
+#define wxLC_SINGLE_SEL 0x2000
+#define wxLC_SORT_ASCENDING 0x4000
+#define wxLC_SORT_DESCENDING 0x8000
+
+#define wxLC_MASK_TYPE (wxLC_ICON | wxLC_SMALL_ICON | wxLC_LIST | wxLC_REPORT)
+#define wxLC_MASK_ALIGN (wxLC_ALIGN_TOP | wxLC_ALIGN_LEFT)
+#define wxLC_MASK_SORT (wxLC_SORT_ASCENDING | wxLC_SORT_DESCENDING)
+
+// for compatibility only
+#define wxLC_USER_TEXT wxLC_VIRTUAL
+
+// Omitted because
+// (a) too much detail
+// (b) not enough style flags
+// (c) not implemented anyhow in the generic version
+//
+// #define wxLC_NO_SCROLL
+// #define wxLC_NO_LABEL_WRAP
+// #define wxLC_OWNERDRAW_FIXED
+// #define wxLC_SHOW_SEL_ALWAYS
+
// Mask flags to tell app/GUI what fields of wxListItem are valid
#define wxLIST_MASK_STATE 0x0001
#define wxLIST_MASK_TEXT 0x0002
// Returns the item or -1 if unsuccessful.
long GetNextItem(long item, int geometry = wxLIST_NEXT_ALL, int state = wxLIST_STATE_DONTCARE) const ;
- // Implementation: converts wxWindows style to MSW style.
- // Can be a single style flag or a bit list.
- // oldStyle is 'normalised' so that it doesn't contain
- // conflicting styles.
- long ConvertToMSWStyle(long& oldStyle, long style) const;
-
// Gets one of the three image lists
wxImageList *GetImageList(int which) const ;
void SetImageList(wxImageList *imageList, int which) ;
void AssignImageList(wxImageList *imageList, int which) ;
+ // returns true if it is a virtual list control
+ bool IsVirtual() const { return (GetWindowStyle() & wxLC_VIRTUAL) != 0; }
+
// Operations
////////////////////////////////////////////////////////////////////////////
int format = wxLIST_FORMAT_LEFT,
int width = -1);
+ // set the number of items in a virtual list control
+ void SetItemCount(long count);
+
// Scrolls the list control. If in icon, small icon or report view mode,
// x specifies the number of pixels to scroll. If in list view mode, x
// specifies the number of columns to scroll.
// bring the control in sync with current m_windowStyle value
void UpdateStyle();
- // Add to pool: necessary because Windows needs to have a string
- // still exist across 3 callbacks.
- wxChar *AddPool(const wxString& str);
+ // Implementation: converts wxWindows style to MSW style.
+ // Can be a single style flag or a bit list.
+ // oldStyle is 'normalised' so that it doesn't contain
+ // conflicting styles.
+ long ConvertToMSWStyle(long& oldStyle, long style) const;
// Event handlers
////////////////////////////////////////////////////////////////////////////
m_ownsImageListState;
long m_baseStyle; // Basic Windows style flags, for recreation purposes
- wxStringList m_stringPool; // Pool of 3 strings to satisfy Windows callback requirements
int m_colCount; // Windows doesn't have GetColumnCount so must
// keep track of inserted/deleted columns
// TRUE if we have any items with custom attributes
bool m_hasAnyAttr;
+ // these functions are only used for virtual list view controls, i.e. the
+ // ones with wxLC_VIRTUAL style
+
+ // return the text for the given column of the given item
+ virtual wxString OnGetItemText(long item, long column) const;
+
+ // return the icon for the given item
+ virtual int OnGetItemImage(long item) const;
+
private:
bool DoCreateControl(int x, int y, int w, int h);
#include "listtest.h"
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
- EVT_MENU(BUSY_ON, MyFrame::BusyOn)
- EVT_MENU(BUSY_OFF, MyFrame::BusyOff)
+ EVT_SIZE(MyFrame::OnSize)
+
EVT_MENU(LIST_QUIT, MyFrame::OnQuit)
EVT_MENU(LIST_ABOUT, MyFrame::OnAbout)
EVT_MENU(LIST_LIST_VIEW, MyFrame::OnListView)
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_TOGGLE_FIRST, MyFrame::OnToggleFirstSel)
EVT_MENU(LIST_DESELECT_ALL, MyFrame::OnDeselectAll)
EVT_MENU(LIST_SELECT_ALL, MyFrame::OnSelectAll)
EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour)
EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel)
EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo)
+
EVT_UPDATE_UI(LIST_SHOW_COL_INFO, MyFrame::OnUpdateShowColInfo)
END_EVENT_TABLE()
// Make a menubar
wxMenu *menuFile = new wxMenu;
- menuFile->Append(LIST_ABOUT, "&About");
+ menuFile->Append(LIST_ABOUT, _T("&About"));
menuFile->AppendSeparator();
-#if 0 // what is this for? (VZ)
- menuFile->Append(BUSY_ON, "&Busy cursor on");
- menuFile->Append(BUSY_OFF, "&Busy cursor off");
- menuFile->AppendSeparator();
-#endif
- menuFile->Append(LIST_QUIT, "E&xit\tAlt-X");
+ menuFile->Append(LIST_QUIT, _T("E&xit\tAlt-X"));
wxMenu *menuView = new wxMenu;
- menuView->Append(LIST_LIST_VIEW, "&List view\tF1");
- menuView->Append(LIST_REPORT_VIEW, "&Report view\tF2");
- menuView->Append(LIST_ICON_VIEW, "&Icon view\tF3");
- menuView->Append(LIST_ICON_TEXT_VIEW, "Icon view with &text\tF4");
- menuView->Append(LIST_SMALL_ICON_VIEW, "&Small icon view\tF5");
- menuView->Append(LIST_SMALL_ICON_TEXT_VIEW, "Small icon &view with text\tF6");
+ menuView->Append(LIST_LIST_VIEW, _T("&List view\tF1"));
+ menuView->Append(LIST_REPORT_VIEW, _T("&Report view\tF2"));
+ menuView->Append(LIST_ICON_VIEW, _T("&Icon view\tF3"));
+ menuView->Append(LIST_ICON_TEXT_VIEW, _T("Icon view with &text\tF4"));
+ menuView->Append(LIST_SMALL_ICON_VIEW, _T("&Small icon view\tF5"));
+ menuView->Append(LIST_SMALL_ICON_TEXT_VIEW, _T("Small icon &view with text\tF6"));
+ menuView->Append(LIST_VIRTUAL_VIEW, _T("Virtual view\tF7"));
wxMenu *menuList = new wxMenu;
- menuList->Append(LIST_TOGGLE_FIRST, "&Toggle first item\tCtrl-T");
- menuList->Append(LIST_DESELECT_ALL, "&Deselect All\tCtrl-D");
- menuList->Append(LIST_SELECT_ALL, "S&elect All\tCtrl-A");
- menuList->Append(LIST_SHOW_COL_INFO, "Show &column info\tCtrl-C");
+ menuList->Append(LIST_TOGGLE_FIRST, _T("&Toggle first item\tCtrl-T"));
+ menuList->Append(LIST_DESELECT_ALL, _T("&Deselect All\tCtrl-D"));
+ menuList->Append(LIST_SELECT_ALL, _T("S&elect All\tCtrl-A"));
+ menuList->Append(LIST_SHOW_COL_INFO, _T("Show &column info\tCtrl-C"));
menuList->AppendSeparator();
- menuList->Append(LIST_SORT, "&Sort\tCtrl-S");
+ menuList->Append(LIST_SORT, _T("&Sort\tCtrl-S"));
menuList->AppendSeparator();
- menuList->Append(LIST_DELETE, "&Delete first item");
- menuList->Append(LIST_DELETE_ALL, "Delete &all items");
+ menuList->Append(LIST_DELETE, _T("&Delete first item"));
+ menuList->Append(LIST_DELETE_ALL, _T("Delete &all items"));
menuList->AppendSeparator();
- menuList->Append(LIST_TOGGLE_MULTI_SEL, "&Multiple selection\tCtrl-M",
- "Toggle multiple selection", TRUE);
+ menuList->Append(LIST_TOGGLE_MULTI_SEL, _T("&Multiple selection\tCtrl-M"),
+ _T("Toggle multiple selection"), TRUE);
wxMenu *menuCol = new wxMenu;
- menuCol->Append(LIST_SET_FG_COL, "&Foreground colour...");
- menuCol->Append(LIST_SET_BG_COL, "&Background colour...");
+ menuCol->Append(LIST_SET_FG_COL, _T("&Foreground colour..."));
+ menuCol->Append(LIST_SET_BG_COL, _T("&Background colour..."));
wxMenuBar *menubar = new wxMenuBar;
- menubar->Append(menuFile, "&File");
- menubar->Append(menuView, "&View");
- menubar->Append(menuList, "&List");
- menubar->Append(menuCol, "&Colour");
+ menubar->Append(menuFile, _T("&File"));
+ menubar->Append(menuView, _T("&View"));
+ menubar->Append(menuList, _T("&List"));
+ menubar->Append(menuCol, _T("&Colour"));
SetMenuBar(menubar);
m_listCtrl = new MyListCtrl(this, LIST_CTRL,
wxLC_LIST |
wxSUNKEN_BORDER |
wxLC_EDIT_LABELS |
- // wxLC_USER_TEXT requires app to supply all
- // text on demand
- //wxLC_USER_TEXT |
wxLC_SINGLE_SEL
);
m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_logWindow));
- wxLayoutConstraints *c = new wxLayoutConstraints;
- c->top.SameAs (this, wxTop);
- c->left.SameAs (this, wxLeft);
- c->right.SameAs (this, wxRight);
- c->height.PercentOf (this, wxHeight, 66);
- m_listCtrl->SetConstraints(c);
-
- c = new wxLayoutConstraints;
- c->top.Below (m_listCtrl);
- c->left.SameAs (this, wxLeft);
- c->right.SameAs (this, wxRight);
- c->bottom.SameAs (this, wxBottom);
- m_logWindow->SetConstraints(c);
- SetAutoLayout(TRUE);
-
for ( int i = 0; i < 30; i++ )
{
long idx = m_listCtrl->InsertItem(i, wxString::Format(_T("Item %d"), i));
delete m_imageListSmall;
}
-void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+void MyFrame::OnSize(wxSizeEvent& event)
{
- Close(TRUE);
-}
+ if ( !m_logWindow )
+ return;
-void MyFrame::BusyOn(wxCommandEvent& WXUNUSED(event))
-{
- wxBeginBusyCursor();
+ wxSize size = GetClientSize();
+ wxCoord y = (2*size.y)/3;
+ m_listCtrl->SetSize(0, 0, size.x, y);
+ m_logWindow->SetSize(0, y + 1, size.x, size.y - y);
+
+ event.Skip();
}
-void MyFrame::BusyOff(wxCommandEvent& WXUNUSED(event))
+void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
- wxEndBusyCursor();
+ Close(TRUE);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
for ( int i=0; i < 30; i++)
{
- wxChar buf[20];
- wxSprintf(buf, _T("Item %d"), i);
- m_listCtrl->InsertItem(i, buf);
+ m_listCtrl->InsertItem(i, wxString::Format(_T("Item %d"), i));
}
}
}
}
+void MyFrame::OnVirtualView(wxCommandEvent& WXUNUSED(event))
+{
+#ifdef __WXMSW__
+ m_logWindow->Clear();
+
+ // we really have to recreate it
+ delete m_listCtrl;
+
+ m_listCtrl = new MyListCtrl(this, LIST_CTRL,
+ wxDefaultPosition, wxDefaultSize,
+ wxLC_REPORT |
+ wxSUNKEN_BORDER |
+ wxLC_SINGLE_SEL |
+ wxLC_VIRTUAL
+ );
+
+ m_listCtrl->InsertColumn(0, "First Column");
+ m_listCtrl->InsertColumn(1, "Second Column");
+ m_listCtrl->SetColumnWidth(0, 150);
+ m_listCtrl->SetColumnWidth(1, 150);
+
+ m_listCtrl->SetItemCount(1000000);
+
+ SendSizeEvent();
+#else
+ wxLogError(_T("Sorry, not implemented"));
+#endif
+}
+
void MyFrame::OnSort(wxCommandEvent& WXUNUSED(event))
{
wxStopWatch sw;
event.GetText().c_str(), event.GetData());
}
+wxString MyListCtrl::OnGetItemText(long item, long column) const
+{
+ return wxString::Format(_T("Column %ld of item %ld"), column, item);
+}
+
+int MyListCtrl::OnGetItemImage(long item) const
+{
+ return 0;
+}
+
private:
void LogEvent(const wxListEvent& event, const wxChar *eventName);
+ virtual wxString OnGetItemText(long item, long column) const;
+ virtual int OnGetItemImage(long item) const;
+
DECLARE_EVENT_TABLE()
};
~MyFrame();
public:
+ void OnSize(wxSizeEvent& event);
+
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnListView(wxCommandEvent& event);
void OnIconTextView(wxCommandEvent& event);
void OnSmallIconView(wxCommandEvent& event);
void OnSmallIconTextView(wxCommandEvent& event);
+ void OnVirtualView(wxCommandEvent& event);
+
void OnToggleFirstSel(wxCommandEvent& event);
void OnDeselectAll(wxCommandEvent& event);
void OnSelectAll(wxCommandEvent& event);
void OnSetBgColour(wxCommandEvent& event);
void OnToggleMultiSel(wxCommandEvent& event);
void OnShowColInfo(wxCommandEvent& event);
- void OnUpdateShowColInfo(wxUpdateUIEvent& event);
- void BusyOn(wxCommandEvent& event);
- void BusyOff(wxCommandEvent& event);
+ void OnUpdateShowColInfo(wxUpdateUIEvent& event);
wxImageList *m_imageListNormal;
wxImageList *m_imageListSmall;
};
-// ID for the menu quit command
+// IDs for the menu commands
enum
{
- LIST_QUIT = 1,
- LIST_LIST_VIEW = 2,
- LIST_ICON_VIEW = 3,
- LIST_ICON_TEXT_VIEW = 4,
- LIST_SMALL_ICON_VIEW = 5,
- LIST_SMALL_ICON_TEXT_VIEW = 6,
- LIST_REPORT_VIEW = 7,
- LIST_DESELECT_ALL = 8,
- LIST_SELECT_ALL = 9,
- LIST_ABOUT = 102,
- BUSY_ON = 10,
- BUSY_OFF = 11,
- LIST_DELETE_ALL = 12,
+ LIST_QUIT,
+ LIST_LIST_VIEW,
+ LIST_ICON_VIEW,
+ LIST_ICON_TEXT_VIEW,
+ LIST_SMALL_ICON_VIEW,
+ LIST_SMALL_ICON_TEXT_VIEW,
+ LIST_VIRTUAL_VIEW,
+
+ LIST_REPORT_VIEW,
+ LIST_DESELECT_ALL,
+ LIST_SELECT_ALL,
+ LIST_ABOUT,
+ LIST_DELETE_ALL,
LIST_DELETE,
LIST_SORT,
LIST_SET_FG_COL,
#include "wx/intl.h"
#endif
+#include "wx/listctrl.h"
+
#if wxUSE_RADIOBTN
#include "wx/radiobut.h"
#endif
#pragma hdrstop
#endif
-#if wxUSE_LISTCTRL
-
-#ifdef __WIN95__
+#if wxUSE_LISTCTRL && defined(__WIN95__)
#ifndef WX_PRECOMP
#include "wx/app.h"
if ( style & wxLC_AUTOARRANGE )
wstyle |= LVS_AUTOARRANGE;
- // Apparently, no such style (documentation wrong?)
- /*
- if ( style & wxLC_BUTTON )
- wstyle |= LVS_BUTTON;
- */
-
if ( style & wxLC_NO_SORT_HEADER )
wstyle |= LVS_NOSORTHEADER;
wstyle |= LVS_SORTDESCENDING;
}
+ if ( style & wxLC_VIRTUAL )
+ {
+ wstyle |= LVS_OWNERDATA;
+ }
+
return wstyle;
}
// -1 otherwise.
long wxListCtrl::InsertItem(wxListItem& info)
{
+ wxASSERT_MSG( !IsVirtual(), _T("can't be used with virtual controls") );
+
LV_ITEM item;
wxConvertToMSWListItem(this, info, item);
}
break;
- case LVN_GETDISPINFO:
- // this provokes stack overflow: indeed, wxConvertFromMSWListItem()
- // sends us WM_NOTIFY! As it doesn't do anything for now, just leave
- // it out.
-#if 0
- {
- // TODO: some text buffering here, I think
- // TODO: API for getting Windows to retrieve values
- // on demand.
- eventType = wxEVT_COMMAND_LIST_GET_INFO;
- LV_DISPINFO *info = (LV_DISPINFO *)lParam;
- wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
- break;
- }
-#endif // 0
- return FALSE;
-
-
case LVN_INSERTITEM:
eventType = wxEVT_COMMAND_LIST_INSERT_ITEM;
event.m_itemIndex = nmLV->iItem;
// break; // can never be reached
#endif // _WIN32_IE >= 0x300
+ case LVN_GETDISPINFO:
+ if ( IsVirtual() )
+ {
+ LV_DISPINFO *info = (LV_DISPINFO *)lParam;
+
+ LV_ITEM& lvi = info->item;
+ long item = lvi.iItem;
+
+ if ( lvi.mask & LVIF_TEXT )
+ {
+ wxString text = OnGetItemText(item, lvi.iSubItem);
+ wxStrncpy(lvi.pszText, text, lvi.cchTextMax);
+ }
+
+ if ( lvi.mask & LVIF_IMAGE )
+ {
+ lvi.iImage = OnGetItemImage(item);
+ }
+
+ // a little dose of healthy paranoia: as we never use
+ // LVM_SETCALLBACKMASK we're not supposed to get these ones
+ wxASSERT_MSG( !(lvi.mask & LVIF_STATE),
+ _T("we don't support state callbacks yet!") );
+
+ return TRUE;
+ }
+ // fall through
+
default:
return wxControl::MSWOnNotify(idCtrl, lParam, result);
}
return TRUE;
- case LVN_GETDISPINFO:
- {
- LV_DISPINFO *info = (LV_DISPINFO *)lParam;
- if ( info->item.mask & LVIF_TEXT )
- {
- if ( !event.m_item.m_text.IsNull() )
- {
- info->item.pszText = AddPool(event.m_item.m_text);
- info->item.cchTextMax = wxStrlen(info->item.pszText) + 1;
- }
- }
- // wxConvertToMSWListItem(this, event.m_item, info->item);
- break;
- }
case LVN_ENDLABELEDIT:
{
*result = event.IsAllowed();
return TRUE;
}
-wxChar *wxListCtrl::AddPool(const wxString& str)
-{
- // Remove the first element if 3 strings exist
- if ( m_stringPool.Number() == 3 )
- {
- wxNode *node = m_stringPool.First();
- delete[] (char *)node->Data();
- delete node;
- }
- wxNode *node = m_stringPool.Add(WXSTRINGCAST str);
- return (wxChar *)node->Data();
-}
-
// Necessary for drawing hrules and vrules, if specified
void wxListCtrl::OnPaint(wxPaintEvent& event)
{
}
}
+// ----------------------------------------------------------------------------
+// virtual list controls
+// ----------------------------------------------------------------------------
+
+wxString wxListCtrl::OnGetItemText(long item, long col) const
+{
+ // this is a pure virtual function, in fact - which is not really pure
+ // because the controls which are not virtual don't need to implement it
+ wxFAIL_MSG( _T("not supposed to be called") );
+
+ return wxEmptyString;
+}
+
+int wxListCtrl::OnGetItemImage(long item) const
+{
+ // same as above
+ wxFAIL_MSG( _T("not supposed to be called") );
+
+ return -1;
+}
+
+void wxListCtrl::SetItemCount(long count)
+{
+ wxASSERT_MSG( IsVirtual(), _T("this is for virtual controls only") );
+
+ if ( !::SendMessage(GetHwnd(), LVM_SETITEMCOUNT, (WPARAM)count, 0) )
+ {
+ wxLogLastError(_T("ListView_SetItemCount"));
+ }
+}
+
// ----------------------------------------------------------------------------
// wxListItem
// ----------------------------------------------------------------------------
m_cancelled = FALSE;
}
-#endif // __WIN95__
-
#endif // wxUSE_LISTCTRL