wxListCtrl
BlitzMax 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 |
| ||
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 ListCtrlTest.bmx 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 |
| ||
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 |
| ||
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 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 ListCtrlTest.bmx 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. |