wxListCtrl

BlitzMax Modules Forums/Brucey's Modules/wxListCtrl

I have stripped back Bruceys sample ListCtrl to just the parts i want.
I am not sure why
Method InsertItemInReportView(i:Int)
needs to be in a seperate type.
anyone got a simple explanation?

cheers
glenn

'
' wxListCtrl sample
'
' From the C++ sample by Julian Smart
'
' BlitzMax port by Bruce A Henderson
'
SuperStrict

Framework wx.wxApp
Import wx.wxListCtrl
Import wx.wxFrame
Import wx.wxPanel
Import wx.wxSystemSettings
Import wx.wxMouseEvent

Const LIST_CTRL:Int = 1000

' number of items in list/report view
Const NUM_ITEMS:Int = 30

' number of items in icon/small icon view
Const NUM_ICONS:Int = 9

New MyApp.run()

Type MyApp Extends wxApp

	Method OnInit:Int()
	
		wxImage.AddHandler( New wxXPMHandler ) ' for Mac/Win32 (it is default on Linux)

		Local frame:MyFrame = MyFrame(New MyFrame.Create(, , "wxListCtrl Test"))

		frame.show()
		
		SetTopWindow(frame)
	
		Return True
	
	End Method

End Type

Type MyFrame Extends wxFrame

	Field panel:wxPanel
	Field listCtrl:MyListCtrl

	Method OnInit()
		DoConnections()
	
		If wxSystemSettings.GetScreenType() > wxSYS_SCREEN_SMALL Then
			SetSize(450, 340)
		End If

		panel = New wxPanel.Create(Self, wxID_ANY)

		RecreateList(wxLC_REPORT | wxLC_SINGLE_SEL)

	End Method
	
	Method DoConnections()

	End Method

	' recreate the list control with the New flags
	Method RecreateList(flags:Int, withText:Int = True)

		If listCtrl Then
			listCtrl.Free()
		End If

		listCtrl = MyListCtrl(New MyListCtrl.Create(panel, LIST_CTRL, ,, ,, flags | wxSUNKEN_BORDER | wxLC_EDIT_LABELS))
		
		Select flags & wxLC_MASK_TYPE
			
			Case wxLC_REPORT
				If flags & wxLC_VIRTUAL Then
				Else
					InitWithReportItems()
				End If
			
			Default
				'wxFAIL_MSG( _T("unknown listctrl mode") );
		End Select
		
		
		DoSize()
	End Method
	
	Method DoSize()

		Local w:Int, h:Int
		GetClientSize(w, h)
		Local y:Int = (2 * h) / 3
		listCtrl.SetDimensions(0, 0, w, y)

	End Method

	Method InitWithReportItems()

		' note that under MSW For SetColumnWidth() To work we need To create the
		' items with images initially even If we specify dummy image id
		Local itemCol:wxListItem = New wxListItem.Create()
		itemCol.SetText("Column 1")
		itemCol.SetImage(-1)
		listCtrl.InsertColumnItem(0, itemCol)
		
		itemCol.SetText("Column 2")
		itemCol.SetAlign(wxLIST_FORMAT_CENTRE)
		listCtrl.InsertColumnItem(1, itemCol)
		
		itemCol.SetText("Column 3")
		itemCol.SetAlign(wxLIST_FORMAT_RIGHT)
		listCtrl.InsertColumnItem(2, itemCol)
		
		' To speed up inserting we hide the control temporarily
		listCtrl.Hide()
		
		For Local i:Int = 0 Until NUM_ITEMS
			listCtrl.InsertItemInReportView(i)
		Next
		
		listCtrl.Show()
		
		' we leave all mask fields To 0 And only change the colour
		Local item:wxListItem = New wxListItem.Create()
		item.SetId(0)
		item.SetTextColour(wxRED())
		listCtrl.SetItem( item )
		
		item.SetId(2)
		item.SetTextColour(wxGREEN())
		listCtrl.SetItem( item )
		
		item.SetId(4)
		item.SetTextColour(wxLIGHT_GREY())
		item.SetFont(wxITALIC_FONT())
		item.SetBackgroundColour(wxRED())
		listCtrl.SetItem( item );
		
		listCtrl.SetTextColour(wxBLUE())
		
		listCtrl.SetColumnWidth( 0, wxLIST_AUTOSIZE )
		listCtrl.SetColumnWidth( 1, wxLIST_AUTOSIZE )
		listCtrl.SetColumnWidth( 2, wxLIST_AUTOSIZE )
		
		' Set images in columns
		listCtrl.SetItemColumnImage(1, 1, 0)
		
		Local info:wxListItem = New wxListItem.Create()
		info.SetImage(0)
		info.SetId(3)
		info.SetColumn(2)
		listCtrl.SetItem(info)
		
		' test SetItemFont too
		listCtrl.SetItemFont(0, wxITALIC_FONT())
	End Method
End Type



Type MyListCtrl Extends wxListCtrl

	Method OnInit()
	End Method

	Method InsertItemInReportView(i:Int)
		Local buf:String = "This is item " + i
		Local tmp:Int = InsertImageStringItem(i, buf, 0)
		
		buf = "Col 1, item " + i
		SetStringItem(tmp, 1, buf)
		
		buf = "Item " + i + " in column 2"
		SetStringItem(tmp, 2, buf)
	End Method

End Type



answer found

listCtrl = MyListCtrl(New MyListCtrl.Create(panel, LIST_CTRL, ,, ,, flags | wxSUNKEN_BORDER | wxLC_EDIT_LABELS))

doh !!!

Okay - After several days of trying to get my own data from a DataBase type into a ListCtrl i have brought it back to the Sample Program, and configured how i am doing it in the real program.

I have a GUI file and the Main file.
The main file doesn't seem to compile on :
For Local i:Int = 0 Until 4
m_listCtrlTEST.InsertItemInReportView(i)
Next

m_listCtrlTEST is the listctrl from the gui file.
it complains about InsertItemInReportView though and not being able to find it. This is in the seperate MyListCtrl type, based on the sample. I have added the listctrl as a field of MyListCtrl on the off chance that helps...

I have a seperate TDataSet (not being used in this example yet) which i planned to use later.

Any suggestions welcomed.

ListCtrlTestGUI.bmx
'
' BlitzMax code generated with wxCodeGen v1.00 : 02 Mar 2008 15:03:08
' 
' 
' PLEASE DO "NOT" EDIT THIS FILE!
' 
SuperStrict

Import wx.wxFrame
Import wx.wxListCtrl
Import wx.wxPanel
Import wx.wxWindow


Type MyFrame2Base Extends wxFrame

	Field m_panel2:wxPanel
	Field m_listCtrlTEST:wxListCtrl

	Const IDListCtrlTEST:Int = 1000

	Method Create:MyFrame2Base(parent:wxWindow = Null,id:Int = wxID_ANY, title:String = "", x:Int = -1, y:Int = -1, w:Int = 500, h:Int = 300, style:Int = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL)
		Return MyFrame2Base(Super.Create(parent, id, title, x, y, w, h, style))
	End Method

	Method OnInit()

		Local bSizer18:wxBoxSizer
		bSizer18 = New wxBoxSizer.Create(wxVERTICAL)
		m_panel2 = New wxPanel.Create(Self, wxID_ANY,,,,, wxTAB_TRAVERSAL)

		Local bSizer19:wxBoxSizer
		bSizer19 = New wxBoxSizer.Create(wxVERTICAL)
		m_listCtrlTEST = New wxListCtrl.Create(m_panel2, IDListCtrlTEST,,,,, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL)
		m_listCtrlTEST.SetMinSize(400,200)
		bSizer19.Add(m_listCtrlTEST, 1, wxALL, 5)

		m_panel2.SetSizer(bSizer19)
		m_panel2.Layout()
		bSizer18.Add(m_panel2, 1, wxEXPAND | wxALL, 5)

		SetSizer(bSizer18)
		Layout()

	End Method

End Type



ListCtrlTest.bmx
'
' Example application stub generated by wxCodeGen v1.00 : 02 Mar 2008 15:03:08
'
SuperStrict

Framework wx.wxApp

Import "ListCtrlTestGUI.bmx"
Import brl.LinkedList

New MyApp.run()

Type MyApp Extends wxApp

	Field frame:MyFrame2
	
	Method OnInit:Int()

?macos
		' make the default Mac font for controls not so big
		wxSystemOptions.SetOption(wxWINDOW_DEFAULT_VARIANT, wxWINDOW_VARIANT_SMALL)
?
		wxInitAllImageHandlers()

		wxImage.AddHandler( New wxXPMHandler ) ' for Mac/Win32 (it is default on Linux)

		Local frame:MyFrame2 = MyFrame2(New MyFrame2.Create(, , "C2D TaskList ListCtrl Test"))

		frame.show()
		
		SetTopWindow(frame)

		Return True
	End Method

End Type



Type MyFrame2 Extends MyFrame2Base

	' added from Bruceys Example
	Field imageListSmall:wxImageList
	' my columns to be used for the TDataSet ***** but NOT used in this example
	Global s_ColumnTitles:String[] = ["Column1","Column2","Column3","Column4","Column5"]
	
	
	Method OnInit()
		Super.OnInit()
		' added from Bruceys Example
		imageListSmall = New wxImageList.Create(16, 16, True)
		RecreateList(wxLC_REPORT | wxLC_SINGLE_SEL)
	End Method


	Method InitWithReportItems()
		m_listCtrlTEST.SetImageList(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
		Local itemCol:wxListItem = New wxListItem.Create()
		itemCol.SetText("Column 1")
		itemCol.SetImage(-1)
		m_listCtrlTEST.InsertColumnItem(0, itemCol)
		
		itemCol.SetText("Column 2")
		itemCol.SetAlign(wxLIST_FORMAT_CENTRE)
		m_listCtrlTEST.InsertColumnItem(1, itemCol)
		
		itemCol.SetText("Column 3")
		itemCol.SetAlign(wxLIST_FORMAT_RIGHT)
		m_listCtrlTEST.InsertColumnItem(2, itemCol)
		
		' To speed up inserting we hide the control temporarily
		m_listCtrlTEST.Hide()
		
		For Local i:Int = 0 Until 4
			m_listCtrlTEST.InsertItemInReportView(i)
		Next
		
		m_listCtrlTEST.Show()
		
		' we leave all mask fields To 0 And only change the colour
		Local item:wxListItem = New wxListItem.Create()
		item.SetId(0)
		item.SetTextColour(wxRED())
		m_listCtrlTEST.SetItem( item )
		
		item.SetId(2)
		item.SetTextColour(wxGREEN())
		m_listCtrlTEST.SetItem( item )
		
		item.SetId(4)
		item.SetTextColour(wxLIGHT_GREY())
		item.SetFont(wxITALIC_FONT())
		item.SetBackgroundColour(wxRED())
		m_listCtrlTEST.SetItem( item );
		
		m_listCtrlTEST.SetTextColour(wxBLUE())
		
		m_listCtrlTEST.SetColumnWidth( 0, wxLIST_AUTOSIZE )
		m_listCtrlTEST.SetColumnWidth( 1, wxLIST_AUTOSIZE )
		m_listCtrlTEST.SetColumnWidth( 2, wxLIST_AUTOSIZE )
		
		' Set images in columns
		m_listCtrlTEST.SetItemColumnImage(1, 1, 0)
		
		Local info:wxListItem = New wxListItem.Create()
		info.SetImage(0)
		info.SetId(3)
		info.SetColumn(2)
		m_listCtrlTEST.SetItem(info)
		
		' test SetItemFont too
		m_listCtrlTEST.SetItemFont(0, wxITALIC_FONT())
	End Method

	' recreate the list control with the New flags
	Method RecreateList(flags:Int, withText:Int = True)

		If m_listCtrlTEST Then
			m_listCtrlTEST.Free()
		End If

		m_listCtrlTEST= MyListCtrl(New MyListCtrl.Create(panel, LIST_CTRL, ,, ,, flags | wxSUNKEN_BORDER | wxLC_EDIT_LABELS))
		
		Select flags & wxLC_MASK_TYPE
			Case wxLC_LIST
'				InitWithListItems()
			
			Case wxLC_ICON
'				InitWithIconItems(withText)
			
			Case wxLC_SMALL_ICON
'				InitWithIconItems(withText, True)
			
			Case wxLC_REPORT
				If flags & wxLC_VIRTUAL Then
'					InitWithVirtualItems()
				Else
					InitWithReportItems()
				End If
			
			Default
			
		End Select
		
		
		DoSize()
		
	End Method
	
	Method DoSize()
		If Not logWindow Then
			Return
		End If

		Local w:Int, h:Int
		GetClientSize(w, h)
		Local y:Int = (2 * h) / 3
		listCtrl.SetDimensions(0, 0, w, y)
		logWindow.SetDimensions(0, y + 1, w, h - y)
	End Method
	
	
End Type

Type MyListCtrl Extends wxListCtrl

	Field m_listCtrlTEST:wxListCtrl
	
	Method InsertItemInReportView(i:Int)
		Local buf:String = "This is item " + i
		Local tmp:Int = InsertImageStringItem(i, buf, 0)
		
		buf = "Col 1, item " + i
		SetStringItem(tmp, 1, buf)
		
		buf = "Item " + i + " in column 2"
		SetStringItem(tmp, 2, buf)
	End Method

End Type

Type TDataSet

	Field c1:Int
	Field c2:String
	Field c3:String
	Field c4:Int
	Field c5:String
		
	Global list:TList
	
	Method Init:TDataSet()
		Return Self
	End Method
	
	Function Create(RowNumber:Int)

		Local DataSet:TDataSet = New TDataSet

		DataSet.c1 = RowNumber
		DataSet.c2 = "Column 2 for Row Number " + RowNumber
		DataSet.c3 = "Column 3 for Row Number " + RowNumber
		DataSet.c4 = 100 + RowNumber
		DataSet.c5 = "Column 5 for Row Number " + RowNumber + " Has a long piece of Data to display"
		
		If Not List Then List = CreateList()
		List.AddLast( DataSet )

	End Function
End Type

Edited 08 March 2008 to stretch as the window is widened.

Put Field m_listCtrlTEST:wxListCtrl in MyFrame2 perhaps?

Me thinks you should rather start afresh and not rely too much on the listctrl sample code.

The problem with the samples is that they tend to show *everything* that a control can do, which is not necessarily what *you* want to do.

Here are some snippets from my current "playing with wxMax" project, SQLiteDBA. It assumes you are using the listctrl in REPORT mode, which is most useful for showing things with rows/columns.

Adding an item to a row in a listctrl (which has several columns)
	Method InsertIntoList(index:Int, list:wxListCtrl)

		Local item:wxListItem = New wxListItem.Create()
		item.SetImage(-1)
		item.SetText(seq)
		item.SetId(index)
		
		list.InsertItem(item)

		item.SetText(name)
		item.SetColumn(1)
		list.SetItem(item)

		item.SetText(Null)
		If unique Then
			item.SetImage(IMG_CHECKED)
		Else
			item.SetImage(IMG_UNCHECKED)
		End If
		item.SetColumn(2)
		list.SetItem(item)

	End Method

SetImage() is telling the item to show a particular image from an image list - obviously an optional thing :-)

When inserting a new row (of more than one column), create a wxListItem object and set it's parts. It's easier. "id" is the row index. User InsertItem() to initially add that row.
For other columns on that row, use SetColumn() on the item to specifiy which column the item is for, and then SetItem() to actually "put" the item in the list at the desired location.


This little snippet sets the column headings :
	Method SetIndexHeadings()
		indexesList.InsertColumn(0, _("Seq"), wxLIST_FORMAT_CENTRE, 60)
		indexesList.InsertColumn(1, _("Name"))
		indexesList.InsertColumn(2, _("Unique"), wxLIST_FORMAT_CENTRE, 80)
	End Method

Note that for a REPORT mode listctl, you'll need column headings. (unless you define the listctrl to hide them).


Hope this helps a bit.

Here's the methd I use to "recreate" the list :

	Method PopulateIndexes(table:TDBATable)
		indexesList.ClearAll()
		SetIndexHeadings()
		
		If table Then
			Local list:TList = table.ListIndexes()
		
			Local i:Int = 0
			For Local index:TDBAIndex = EachIn list
				index.InsertIntoList(i, indexesList)
				i:+ 1
			Next
		End If
	End Method

Notice that the listctrl itself isn't deleted/removed (unlike in the sample, which is doing other things). Calling ClearAll() will remove *all* the data *and* the column headings. So the first thing we do is re-apply the headings.
Then the code iterates through a list of data, and calls the previously mentioned method to actually add the data to the list.

Remember, this is just one way to do everything.

But basically, the steps involved are :

* Clear your list
* Add headers if you need them
* Insert your row items.

:o)

hmmm.
must watch House and Boston Legal, but back into this in a few hours... :)

Here's the listctrl showing a row of data in it :


...it's the listctrl on the right :-)

indexesList.InsertColumn(0, _("Seq"), wxLIST_FORMAT_CENTRE, 60)

What is the underscore for?

Localization :-)

Allows the app to use different languages at some point.

how come SEQ isn't centered in the Tab like Unique is?

No idea. Most likely a wxWidgets bug.

@No idea. Most likely a wxWidgets bug.

wxWidgets correctly centres the label of column 0 when you populate the header manually using wxListItem (including of course a SetAlign() call) and instantiate via InsertColumnItem(col,item).

At least it does on my list controls...

Perhaps the SetAlign() afterwards is forcing it properly.

I've noticed a couple of quirks with working in Report mode.

I seem to be stuck on this:
index:TDBAIndex
what does TDGAIndex refer to in your program?

[EDIT] Problem resolved.

If i uncomment the IMG_CHECKED section it doesn't compile.
I can't track this down.

Regards
Glenn

Use the ListCtrlTestGUI.bmx from the third post

'
' Example application stub generated by wxCodeGen v1.00 : 02 Mar 2008 15:03:08
'
SuperStrict

Framework wx.wxApp

Import "ListCtrlTestGUI.bmx"
Import brl.LinkedList

New MyApp.run()

Type MyApp Extends wxApp

	Field frame:MyFrame2
	Field m_listCtrlTEST:wxListCtrl
	
	Method OnInit:Int()

?macos
		' make the default Mac font for controls not so big
		wxSystemOptions.SetOption(wxWINDOW_DEFAULT_VARIANT, wxWINDOW_VARIANT_SMALL)
?
		wxInitAllImageHandlers()

		wxImage.AddHandler( New wxXPMHandler ) ' for Mac/Win32 (it is default on Linux)

		Local frame:MyFrame2 = MyFrame2(New MyFrame2.Create(, , "C2D TaskList ListCtrl Test"))

		frame.show()

		frame.PopulateList(frame.m_listCtrlTEST)
		
		SetTopWindow(frame)

		Return True
	End Method

End Type



Type MyFrame2 Extends MyFrame2Base

	Method OnInit()
		Super.OnInit()
	End Method

	Method SetIndexHeadings()
		m_listCtrlTEST.InsertColumn(0, ("C1"), wxLIST_FORMAT_CENTRE, 60)
		m_listCtrlTEST.InsertColumn(1, ("C2"))
		m_listCtrlTEST.InsertColumn(2, ("C3"), wxLIST_FORMAT_CENTRE, 80)
		m_listCtrlTEST.InsertColumn(3, ("C4"), wxLIST_FORMAT_CENTRE, 80)
		m_listCtrlTEST.InsertColumn(4, ("C5"), wxLIST_FORMAT_CENTRE, 80)
	End Method

	Method PopulateList(ListControl:wxListCtrl)
		ListControl.ClearAll()
		SetIndexHeadings()
		TDataSet.Create(1)
		TDataSet.Create(2)
		TDataSet.Create(3)
		TDataSet.Create(4)
				
		If ListControl Then
			Local list:TList = TDataSet.DataList
					
			Local i:Int = 0
			For Local dataset:TDataSet = EachIn list
				InsertIntoList(i, dataset, ListControl)
				i:+ 1
			Next

		End If
	End Method

	Method InsertIntoList(index:Int, dataSet:TDataSet, list:wxListCtrl)

		Local item:wxListItem = New wxListItem.Create()
		item.SetImage(-1)
		item.SetText(dataSet.c1)
		item.SetId(index)
		
		list.InsertItem(item)

		item.SetText(dataSet.c2)
		item.SetColumn(1)
		list.SetItem(item)

		item.SetText(dataSet.c3)
		item.SetColumn(2)
		list.SetItem(item)

		item.SetText(dataSet.c4)
'		If dataSet.c4 = 1 Then
'			item.SetImage(IMG_CHECKED)
'		Else
'			item.SetImage(IMG_UNCHECKED)
'		End If
		item.SetColumn(3)
		list.SetItem(item)

		item.SetText(dataSet.c5)
		item.SetColumn(4)
		list.SetItem(item)

	End Method


End Type

Type TDataSet

	Field c1:Int
	Field c2:String
	Field c3:String
	Field c4:Int
	Field c5:String
		
	Global DataList:TList
	
	Method Init:TDataSet()
		Return Self
	End Method
	
	Function Create(RowNumber:Int)

		Local DataSet:TDataSet = New TDataSet

		DataSet.c1 = RowNumber
		DataSet.c2 = "Column 2 for Row Number " + RowNumber
		DataSet.c3 = "Column 3 for Row Number " + RowNumber
		' if RowNumber is even then set to 1 else 0 - used for the checked/unchecked image 
		If RowNumber Mod 2 = 0 Then 
			DataSet.c4 = 1
		Else
			DataSet.c4 = 0
		EndIf
		DataSet.c5 = "Column 5 for Row Number " + RowNumber + " Has a long piece of Data to display"
		
		If Not DataList Then DataList = CreateList()
		DataList.AddLast( DataSet )

	End Function


End Type


Swap IMG_CHECKED for 1
and IMG_UNCHECKED for 0

and assuming, of course, you have an bitmap array for the listctrl?

Otherwise, just setText() with 1 or 0, or Yes or No, etc ?

i spent about an hour last night checking this.
I realised the values were constants but when i went looking for what numbers they should be (i even read the source code) i was looking for IMG_CHECKED when i should have been looking for SetImage().
My only excuse is it was midnight and i have had 6am starts all week, so i was fairly knackered :)

Here is a working example of the ListCtrl with some comments.
Use the ListCtrlTestGUI.bmx from the third post

Thanks to Brucey and David for their help.

Cheers
Glenn

'
' Example application stub generated by wxCodeGen v1.00 : 02 Mar 2008 15:03:08
'
SuperStrict

Framework wx.wxApp
' import the GUI file
Import "ListCtrlTestGUI.bmx"
Import brl.LinkedList

New MyApp.run()

Type MyApp Extends wxApp

	Method OnInit:Int()

?macos
		' make the default Mac font for controls not so big
		wxSystemOptions.SetOption(wxWINDOW_DEFAULT_VARIANT, wxWINDOW_VARIANT_SMALL)
?
		wxInitAllImageHandlers()

		wxImage.AddHandler( New wxXPMHandler ) ' for Mac/Win32 (it is default on Linux)

		Local frame:MyFrame2 = MyFrame2(New MyFrame2.Create(, , "Glenns ListCtrl Test"))

		frame.show()
		' call the method that reads my Data Type and Populates the ListCtrl
		frame.PopulateList(frame.m_listCtrlTEST)
		
		SetTopWindow(frame)

		Return True
	End Method

End Type



Type MyFrame2 Extends MyFrame2Base

	Method OnInit()
		Super.OnInit()
	End Method

	Method SetColumnHeadings()
		' m_listCtrlTEST is the name of the ListCtrl from the GUI file
		m_listCtrlTEST.InsertColumn(0, ("C1"), wxLIST_FORMAT_CENTRE, 20)	' Small Column, Centred
		m_listCtrlTEST.InsertColumn(1, ("C2"), wxLIST_FORMAT_LEFT, 140)		' Larger Column, Left Justified
		m_listCtrlTEST.InsertColumn(2, ("C3"), wxLIST_FORMAT_RIGHT, 120)	' Larger Column, Right Justified
		m_listCtrlTEST.InsertColumn(3, ("C4"), wxLIST_FORMAT_CENTRE, 40)	' Small Column, Centred
		m_listCtrlTEST.InsertColumn(4, ("C5"), wxLIST_FORMAT_CENTRE, 80)	' Medium Column, Centred.
																			' This columns data is quite Long and the column needs to be expanded with the mouse to see it all.

	End Method

	Method PopulateList(ListControl:wxListCtrl)
		' Clear the listctrl, including the column definitions
		ListControl.ClearAll()
		' Reset the Column Definitions
		SetColumnHeadings()
		' Call the Create Function for the TDataSet type multiple times
		TDataSet.Create(1)
		TDataSet.Create(2)
		TDataSet.Create(3)
		TDataSet.Create(4)
		' If the ListCtrl exists (m_listCtrlTEST) then get the list from the TDataSet type
		If ListControl Then
			Local list:TList = TDataSet.DataList
					
			Local i:Int = 0	' i is the row number in the listctrl
			For Local dataset:TDataSet = EachIn list
				' InsertIntoList(Row Number, the data for this element of the list, the name of the ListCtrl)
				InsertIntoList(i, dataset, ListControl)
				' Increment i so you arer always adding to the end of the ListCtrl
				' comment this line out if you want your listctrl populated in reverse, ie i = 0
				i:+ 1
			Next

		End If
	End Method

	Method InsertIntoList(index:Int, dataSet:TDataSet, list:wxListCtrl)
		' wxListItem - This type stores information about a wxListCtrl item or column.
		
		' Some comments taken from <a href="http://www.gibbongames.com/content/view/52/50/" target="_blank">http://www.gibbongames.com/content/view/52/50/</a>
		' wxListItem encapsulates the contents of a given listbox cell.
		' So each row/column combination has its own wxListItem structure.
		Local item:wxListItem = New wxListItem.Create()
		' Define all the parameters for the column, then use list.SetItem(item) to bind it
		item.SetImage(-1)
		item.SetText(dataSet.c1)
		item.SetId(index)
		
		' Apparently Column 0 requires InsertItem, but Column n > 0 requires SetItem (assuming that Column 0 has been previously inserted).
		list.InsertItem(item)

		item.SetText(dataSet.c2)
		item.SetColumn(1)
		list.SetItem(item)

		item.SetText(dataSet.c3)
		item.SetColumn(2)
		list.SetItem(item)

		' you can use SetImage here but you need bitmap array for the listctrl (which i haven't looked up yet)
		If dataSet.c4 = 1 Then
			item.SetText("Yes")
			' itemSetImage(1) ' or img_Checked if you have defined it as a CONST
		Else
			item.SetText("No")
			' itemSetImage(0) ' or img_NotChecked if you have defined it as a CONST
		End If
		item.SetColumn(3)
		list.SetItem(item)

		item.SetText(dataSet.c5)
		item.SetColumn(4)
		list.SetItem(item)

	End Method


End Type

Type TDataSet
	' just a simple DataSet being stored in a TList
	
	Field c1:Int
	Field c2:String
	Field c3:String
	Field c4:Int
	Field c5:String
		
	Global DataList:TList
	
	Method Init:TDataSet()
		Return Self
	End Method
	
	Function Create(RowNumber:Int)

		Local DataSet:TDataSet = New TDataSet

		DataSet.c1 = RowNumber
		DataSet.c2 = "Column 2 : Row No. " + RowNumber
		DataSet.c3 = "Row Number " + RowNumber
		' if RowNumber is even then set to 1 else 0 - used for the Yes/No or the img_Checked/img_NotChecked image 
		If RowNumber Mod 2 = 0 Then 
			DataSet.c4 = 1
		Else
			DataSet.c4 = 0
		EndIf
		DataSet.c5 = "Column 5 for Row Number " + RowNumber + " Has a long piece of Data to display"
		
		If Not DataList Then DataList = CreateList()
		DataList.AddLast( DataSet )

	End Function

End Type


Glad you've got it all working Glenn. The wxListCtrl interface is pretty convoluted - but you get a fair bit of power for your trouble. I would add that you don't need to redo the column headings every Populate() if they haven't changed. If you want to keep the column headers, use DeleteAllItems() to clear the list control instead of ClearAll().

cheers

I have just modified the GUI file so it will stretch if you widen the window.
I using the following code to set the column headers

	Method SetColumnHeadings(ListControl:wxListCtrl)

		Select ListControl
			Case m_listCtrlDue
			
			Case m_listCtrlMainTask
				ListControl.InsertColumn(0, ("TM"), wxLIST_FORMAT_LEFT, 30)	' Team Member Initials
				ListControl.InsertColumn(1, ("Created"), wxLIST_FORMAT_LEFT, cListCtrlDateWidth)
				ListControl.InsertColumn(2, ("Task Name"), wxLIST_FORMAT_LEFT,200)
				ListControl.InsertColumn(3, ("Due Date"), wxLIST_FORMAT_LEFT, cListCtrlDateWidth)
				ListControl.InsertColumn(4, ("Completed"), wxLIST_FORMAT_LEFT, cListCtrlDateWidth)
				ListControl.InsertColumn(5, ("Cancelled"), wxLIST_FORMAT_CENTRE, cListCtrlDateWidth)
			
			Case m_listCtrlSubTask
			
			Default
				DebugLog "You have passed a ListCtrl that doesn't exist"
		End Select
	
	End Method


i would like the Task Name column to stretch to fill the gap as the window widens.
is there a way to do this?
I could get the listctrl width, subtract the other column widths and redefine MainTask width, assuming the ListCtrl itself has a width value that i can get, but it seems a bit "hacky" to me.

Cheers
Glenn

hmmm i can't see a width command for the listctrl, only the columns...

does this work?

SetColumnWidth(col, wxLIST_AUTOSIZE )

wxListCtrl ultimately extends wxWindow so GetRect() should work I think?

does this work?

SetColumnWidth(col, wxLIST_AUTOSIZE )

Not on Mac, I think.. or maybe I was trying to set it during the column creation instead rather... Hmm.

SetColumnWidth(col, wxLIST_AUTOSIZE ) seems to autosize to the contents (not that i have any in their yet - so it becomes very narrow).

Method GetRect(x:Int Var, y:Int Var, w:Int Var, h:Int Var) has these parameters

Local i:int = Self.GetRect(ListControl) ' this is wrong
what should it be?
ListControl is the name of my listctrl

There are two GetRect methods...
The one you mention, takes a list of ints, which are then populated with values (note the "Int Var" declarations).

The other, GetRectRect(), returns a wxRect object, which carries the same detail, but in a single Type.

Method SetColumnHeadings(ListControl:wxListCtrl)

Select ListControl
Case m_listCtrlDue

Case m_listCtrlMainTask
ListControl.InsertColumn(0, ("TM"), wxLIST_FORMAT_LEFT, 30) ' Team Member Initials
ListControl.InsertColumn(1, ("Created"), wxLIST_FORMAT_LEFT, cListCtrlDateWidth)
ListControl.InsertColumn(2, ("Due Date"), wxLIST_FORMAT_LEFT, cListCtrlDateWidth)
ListControl.InsertColumn(3, ("Completed"), wxLIST_FORMAT_LEFT, cListCtrlDateWidth)
ListControl.InsertColumn(4, ("Cancelled"), wxLIST_FORMAT_CENTRE, cListCtrlDateWidth)
' ListControl.InsertColumn(5, ("Task Name"), wxLIST_FORMAT_LEFT,200)
ListControl.InsertColumn(5, ("Task Name"), wxLIST_FORMAT_LEFT,wxLIST_AUTOSIZE)
DebugStop
Local o:Object = ListControl.GetRectRect()
Local i:Int = o.width
'ListControl.SetColumnWidth(5, wxLIST_AUTOSIZE )
Case m_listCtrlSubTask

Default
DebugLog "You have passed a ListCtrl that doesn't exist"
End Select

End Method



Local i:Int = o.width is not liked.
How do i get the field from an object without knowing the field names?

How's about :

Local rect:wxRect = ListControl.GetRectRect()

Some of wxRect's methods :
wxRect::GetBottom
wxRect::GetHeight
wxRect::GetLeft
wxRect::GetPosition
wxRect::GetTopLeft
wxRect::GetTopRight
wxRect::GetBottomLeft
wxRect::GetBottomRight
wxRect::GetRight
wxRect::GetSize
wxRect::GetTop
wxRect::GetWidth
wxRect::GetX
wxRect::GetY
wxRect::Inflate
wxRect::Intersects
wxRect::IsEmpty


:-)

ahh.
learn something new every day.
how might i have found that information? where in the help would it be?

page 392 of the wxWidgetsPrgramming pdf would have been a good start. (Cross-Platform GUI Programming with wxWidgets)

Also wx.mod >> wx.mod >> doc >> Commands.html

guess i am going to need to reread chapter 13 then.
Thanks

What I do is label and bookmark all the main wxMax commands.html's in a "wxMax" Firefox bookmarks folder. Makes it easy then to have lots of quick ref pages ready in different tabs.

Generally, if you can't find the type you are after in the main directory list of wxmax then look in the "core" wx.mod >> wx.mod.

or, Build Modules, then in the navigator choose, Help ->Third Party Modules -> wx.wx

It's listed in the Types summary.

:o)

Or type "wxRect" in the IDE, highlight and press F1. But that would be too easy :-)

*much too easy* :-p

too easy - but first i had to know about wxRect...
Actually i use Help -> Third Party Modules all the time.
i have a bookmark to here too: http://www.wxwidgets.org/manuals/2.8.7/

now i am figuring out how to update the column size on a SizeEvent for the frame.
just need to spend a bit more time then i will post a sample program again.


cheers guys

I have changed the example to allow for the Last column to resize to the maximum length to fit the ListCtrl while the window is being resized.
There is a refreshed GUI file too.

ListCtrlTestGUI.bmx

'
' BlitzMax code generated with wxCodeGen v1.00 : 08 Mar 2008 21:44:49
' 
' 
' PLEASE DO "NOT" EDIT THIS FILE!
' 
SuperStrict

Import wx.wxFrame
Import wx.wxListCtrl
Import wx.wxPanel
Import wx.wxWindow


Type MyFrame2Base Extends wxFrame

	Field m_panel2:wxPanel
	Field m_listCtrlTEST:wxListCtrl

	Const IDListCtrlTEST:Int = 1000

	Method Create:MyFrame2Base(parent:wxWindow = Null,id:Int = wxID_ANY, title:String = "", x:Int = -1, y:Int = -1, w:Int = -1, h:Int = -1, style:Int = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL)
		Return MyFrame2Base(Super.Create(parent, id, title, x, y, w, h, style))
	End Method

	Method OnInit()
		SetMinSize(400,300)

		Local bSizer18:wxBoxSizer
		bSizer18 = New wxBoxSizer.Create(wxHORIZONTAL)
		m_panel2 = New wxPanel.Create(Self, wxID_ANY,,,,, wxTAB_TRAVERSAL)

		Local bSizer19:wxBoxSizer
		bSizer19 = New wxBoxSizer.Create(wxHORIZONTAL)
		m_listCtrlTEST = New wxListCtrl.Create(m_panel2, IDListCtrlTEST,,,,, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL)
		m_listCtrlTEST.SetMinSize(400,200)
		bSizer19.Add(m_listCtrlTEST, 1, wxALL, 5)

		m_panel2.SetSizer(bSizer19)
		m_panel2.Layout()
		bSizer18.Add(m_panel2, 1, wxEXPAND | wxALL, 5)

		SetSizer(bSizer18)
		Layout()
		bSizer18.Fit(Self)

		ConnectAny(wxEVT_SIZE, _WindowResized)
	End Method

	Function _WindowResized(event:wxEvent)
		MyFrame2Base(event.parent).WindowResized(wxSizeEvent(event))
	End Function

	Method WindowResized(event:wxSizeEvent)
		DebugLog "Please override MyFrame2.WindowResized()"
		event.Skip()
	End Method

End Type


ListCtrlTest.bmx
'
' Example application stub generated by wxCodeGen v1.00 : 02 Mar 2008 15:03:08
'
SuperStrict

Framework wx.wxApp
' import the GUI file
Import "ListCtrlTestGUI.bmx"
Import brl.LinkedList

New MyApp.run()

Type MyApp Extends wxApp

	Method OnInit:Int()

?macos
		' make the default Mac font for controls not so big
		wxSystemOptions.SetOption(wxWINDOW_DEFAULT_VARIANT, wxWINDOW_VARIANT_SMALL)
?
		wxInitAllImageHandlers()

		wxImage.AddHandler( New wxXPMHandler ) ' for Mac/Win32 (it is default on Linux)

		Local frame:MyFrame2 = MyFrame2(New MyFrame2.Create(, , "Glenns ListCtrl Test"))

		frame.show()
		' call the method that reads my Data Type and Populates the ListCtrl
		frame.SetColumnHeadings(frame.m_listCtrlTEST)
		frame.PopulateList(frame.m_listCtrlTEST)
		
		SetTopWindow(frame)

		Return True
	End Method

End Type



Type MyFrame2 Extends MyFrame2Base

	Method OnInit()
		Super.OnInit()
	End Method

' **************************************************
' These 2 methods are used to OverRide the Resizing event from the GUI file	
	Method ChangeColumnWidth(ListControl:wxListCtrl)
		DebugLog "ChangeColumnWidth Method Called"
		
		Local rect:wxRect = ListControl.GetRectRect()
		Local ListWidth:Int = rect.GetWidth()
		DebugLog ListWidth
		
		ListControl.SetColumnWidth(4,ListWidth - (20 + 140 + 120 + 40 + 3)) ' The Plus 3 on the end is to remove the scroll bar. Not sure why though
		
	End Method
	
	Method WindowResized(event:wxSizeEvent)
		DebugLog "Called First"
		ChangeColumnWidth(m_listCtrlTEST)
		' LEAVE this line IN or the ListCtrl won't resize with the Window...
		event.Skip()
	End Method
' **************************************************

	Method SetColumnHeadings(ListControl:wxListCtrl)
		' m_listCtrlTEST is the name of the ListCtrl from the GUI file
		ListControl.InsertColumn(0, ("C1"), wxLIST_FORMAT_CENTRE, 20)	' Small Column, Centred
		ListControl.InsertColumn(1, ("C2"), wxLIST_FORMAT_LEFT, 140)		' Larger Column, Left Justified
		ListControl.InsertColumn(2, ("C3"), wxLIST_FORMAT_RIGHT, 120)	' Larger Column, Right Justified
		ListControl.InsertColumn(3, ("C4"), wxLIST_FORMAT_CENTRE, 40)	' Small Column, Centred
		ListControl.InsertColumn(4, ("C5"), wxLIST_FORMAT_CENTRE, 140)	' AutoSized for Contents, Centred.
																			' This columns data is quite Long and the column needs to be expanded with the mouse to see it all.

	End Method

	Method PopulateList(ListControl:wxListCtrl)
		' Clear the listctrl, including the column definitions
		ListControl.DeleteAllItems()
		' Call the Create Function for the TDataSet type multiple times
		TDataSet.Create(1)
		TDataSet.Create(2)
		TDataSet.Create(3)
		TDataSet.Create(4)
		' If the ListCtrl exists (m_listCtrlTEST) then get the list from the TDataSet type
		If ListControl Then
			Local list:TList = TDataSet.DataList
					
			Local i:Int = 0	' i is the row number in the listctrl
			For Local dataset:TDataSet = EachIn list
				' InsertIntoList(Row Number, the data for this element of the list, the name of the ListCtrl)
				InsertIntoList(i, dataset, ListControl)
				' Increment i so you arer always adding to the end of the ListCtrl
				' comment this line out if you want your listctrl populated in reverse, ie i = 0
				i:+ 1
			Next

		End If
	End Method

	Method InsertIntoList(index:Int, dataSet:TDataSet, list:wxListCtrl)
		' wxListItem - This type stores information about a wxListCtrl item or column.
		
		' Some comments taken from <a href="http://www.gibbongames.com/content/view/52/50/" target="_blank">http://www.gibbongames.com/content/view/52/50/</a>
		' wxListItem encapsulates the contents of a given listbox cell.
		' So each row/column combination has its own wxListItem structure.
		Local item:wxListItem = New wxListItem.Create()
		' Define all the parameters for the column, then use list.SetItem(item) to bind it
		item.SetImage(-1)
		item.SetText(dataSet.c1)
		item.SetId(index)
		
		' Apparently Column 0 requires InsertItem, but Column n > 0 requires SetItem (assuming that Column 0 has been previously inserted).
		list.InsertItem(item)

		item.SetText(dataSet.c2)
		item.SetColumn(1)
		list.SetItem(item)

		item.SetText(dataSet.c3)
		item.SetColumn(2)
		list.SetItem(item)

		' you can use SetImage here but you need bitmap array for the listctrl (which i haven't looked up yet)
		If dataSet.c4 = 1 Then
			item.SetText("Yes")
			' itemSetImage(1) ' or img_Checked if you have defined it as a CONST
		Else
			item.SetText("No")
			' itemSetImage(0) ' or img_NotChecked if you have defined it as a CONST
		End If
		item.SetColumn(3)
		list.SetItem(item)

		item.SetText(dataSet.c5)
		item.SetColumn(4)
		list.SetItem(item)

	End Method


End Type

Type TDataSet
	' just a simple DataSet being stored in a TList
	
	Field c1:Int
	Field c2:String
	Field c3:String
	Field c4:Int
	Field c5:String
		
	Global DataList:TList
	
	Method Init:TDataSet()
		Return Self
	End Method
	
	Function Create(RowNumber:Int)

		Local DataSet:TDataSet = New TDataSet

		DataSet.c1 = RowNumber
		DataSet.c2 = "Column 2 : Row No. " + RowNumber
		DataSet.c3 = "Column 2 : Row No. " + RowNumber
		' if RowNumber is even then set to 1 else 0 - used for the Yes/No or the img_Checked/img_NotChecked image 
		If RowNumber Mod 2 = 0 Then 
			DataSet.c4 = 1
		Else
			DataSet.c4 = 0
		EndIf
		DataSet.c5 = "Column 5 : Row No. " + RowNumber
		
		If Not DataList Then DataList = CreateList()
		DataList.AddLast( DataSet )

	End Function

End Type


I have asked Brucey if there is better way to do this, even though this works fine.

Cheers
Glenn

You need to have this in your ChangeColumnWidth() method :
		If ListControl.GetColumnCount() > 0 Then
			ListControl.SetColumnWidth(4,ListWidth - (20 + 140 + 120 + 40))
		End If

to stop it crashing on Mac.

Seems on Mac there's a resize event before you get to add the columns.

I'm not a fan of that row of column width constants - especially the +3

How about:

	Method GetColumnWidth:Int(_list_control:wxListCtrl,_col:Int)
	
		Local width:Int
	
		For Local column:Int = 0 Until _list_control.GetColumnCount()
			If column <> _col Then width :+ _list_control.GetColumnWidth(column)
		Next
		
		If width 
			Local listbox_width:Int
			Local dummy:Int
			_list_control.GetClientSize(listbox_width,dummy)
			width = Max(0,listbox_width - width)
		EndIf
		
		Return width
	
	End Method


And calling with

ListControl.SetColumnWidth(4,GetColumnWidth(ListControl,4))


That said, I probably would have extended the wxListCtrl and placed this code in there, to prevent all this ListControl argument passing.