Difference between revisions of "MultiColumnList"

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Jump to: navigation, search
Line 1: Line 1:
Since I have been harping about documentation in the forums, I thought it best that I put my money where my mouth is. I am not an expert but I would like to share what I have learned and gleaned about the ''MultiColumnList'' widget.
 
 
If you are familiar with the ''Listbox'' widget then the ''MultiColumnList'' will be a natural progression for you. The one thing you need to remember is that every column entry in the ''MultiColumnList'' will have its own instance of a ''ListboxItem'' or ''ListboxTextItem''. The ''MultiColumnList'' has some very nice features built directly into the widget. By default your users can: a) re-arrange the column display order; b) sort (Ascending and Descending) rows by a column; c) change the width of a column. These features can be disabled.
 
 
API References:
 
[http://www.cegui.org.uk/api_reference/classCEGUI_1_1MultiColumnList.html MultiColumnList]
 
[http://www.cegui.org.uk/api_reference/classCEGUI_1_1ListboxItem.html ListboxItem]
 
[http://www.cegui.org.uk/api_reference/classCEGUI_1_1ListboxTextItem.html ListboxTextItem]
 
[http://www.cegui.org.uk/api_reference/classCEGUI_1_1WindowManager.html WindowManager]
 
 
''Please note that the following example source code was gleaned and edited from project specific code so there may be some syntax errors.''
 
 
 
== Creating the ''MultiColumnList'' in code ==
 
== Creating the ''MultiColumnList'' in code ==
  
Line 73: Line 61:
 
mListBox->setColumnHeaderWidth(3, 0.45f);
 
mListBox->setColumnHeaderWidth(3, 0.45f);
 
</pre>
 
</pre>
 
== Adding Data ==
 
Now, lets create a method to add data to our ''MultiColumnList''. Review this code:
 
 
<pre>
 
void addListboxItem(char *c1, char *c2, char *c3, char *c4, bool isSelected)
 
{
 
  // First, we need to add a new row to the Listbox
 
  // mListBox is from the above code, its a class global pointer in my code.
 
  // If you want, you can singleton() the Listbox or pass the pointer to this function.
 
  unsigned int mRow = mListBox->addRow();
 
 
  // Remember, each column is a 'ListboxTextitem' so we need to
 
  // create a new instance for each column.
 
 
  // Column1
 
  // Create our ListboxTextItem instance...
 
  CEGUI::ListboxTextItem* item = new CEGUI::ListboxTextItem((CEGUI::utf8*)c1, 0);
 
  // Note that in 'setItem' we specify '0' for the index/column we want this
 
  // ListboxTextItem to be attached too.
 
  mListBox->setItem(item, 0, mRow);
 
  // Should it be selected? I know this appears weird but yes you can have columns be
 
  // selected or not selected. In other words, its not ROW based, its COLUMN based
 
  // selection. Why? more options and flexibilty!
 
  item->setSelected(isSelected);
 
  // Don't forget to set the selection brush or your item won't get highlighted.
 
  item->setSelectionBrushImage( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MultiListSelectionBrush");
 
  // You could attach some data to this column that is important to you by
 
  // using the 'setUserData' function. Each column could point to a different
 
  // user data source or the same user data source, or nothing at all.
 
  // item->setUserData(MyPointerToSomeData);
 
 
  // Column2
 
  item = new CEGUI::ListboxTextItem((CEGUI::utf8*)c2, 0);
 
  mListBox->setItem(item, 1, mRow);
 
  item->setSelected(isSelected);
 
  item->setSelectionBrushImage( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MultiListSelectionBrush");
 
 
  // Column3
 
  item = new CEGUI::ListboxTextItem((CEGUI::utf8*)c3, 0);
 
  mListBox->setItem(item, 2, mRow);
 
  item->setSelected(isSelected);
 
  item->setSelectionBrushImage( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MultiListSelectionBrush");
 
 
  //Column4
 
  item = new CEGUI::ListboxTextItem((CEGUI::utf8*)c4, 0);
 
  mListBox->setItem(item, 3, mRow);
 
  item->setSelected(isSelected);
 
  item->setSelectionBrushImage( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MultiListSelectionBrush");
 
 
} // addListboxItem
 
 
</pre>
 
 
 
Now, somewhere in your code, call the ''addListboxItem'' function like this:
 
 
<pre>
 
  ...
 
  addListboxItem("Item1 Col1", "Item1 Col2", "Item1 Col3", "Item1 Col4", true);
 
  addListboxItem("Item2 Col1", "Item2 Col2", "Item2 Col3", "Item2 Col4", false);
 
  addListboxItem("Item3 Col1", "Item3 Col2", "Item3 Col3", "Item3 Col4", false);
 
  addListboxItem("Item4 Col1", "Item4 Col2", "Item4 Col3", "Item4 Col4", true);
 
  ...
 
</pre>
 
 
You will note that in the above source code I have specified two rows to be highlighted. This is possible because of the
 
<pre>
 
mListBox->setSelectionMode(CEGUI::MultiColumnList::SelectionMode::RowMultiple);
 
</pre>
 
statement from above. Review the API documentation about the ''setSelectionMode''. You can make it single row based or column based.
 
 
Program this and give it a try. When you run your program don't forget to re-arrange the column order (drag and drop the column header), resize columns and double click a column header to sort the rows via the clicked column.
 
 
== Other Notable Items ==
 
 
'''At least one column is required.''' You '''must''' have defined at least one column using the ''addColumn()'' method or you will get an error when you attempt to insert a row using the ''addRow()'' funtion.
 
 
'''Odd Column Sizes.''' After the window is created the columns may appear funny - that is, the columns and the data won't appear aligned. There appears to be an initial 'redraw' bug in the library. If you manually resize a column (yes, with the mouse like in windows) it will correct the column layout, spacing and alignment. Also remember that you should '''not''' follow each ''addColumn()'' with a ''setColumnHeaderWidth()''. Create all the columns first and then set the column widths. Not following this will yield unreliable column size results. See the example above.
 
 
'''Drag and Drop.''' As of version 0.4.0 you can not use the CEGUI Drag and Drop feature with ''ListboxTextItem''. Drag and Drop only works with ''Window'' based widgets right now.
 

Revision as of 22:05, 8 October 2005

Creating the MultiColumnList in code

Take a look at this code on how we create the MultiColumnList window:

// Get the CEGUI Window Manager
CEGUI::WindowManager *mWinMgr = CEGUI::WindowManager::getSingletonPtr();

// Create the CEGUI MultiColumnList window
CEGUI::MultiColumnList *mListBox = (CEGUI::MultiColumnList *)mWinMgr->createWindow(
(CEGUI::utf8*)CEGUILOOK"/MultiColumnList", (CEGUI::utf8*)"MyListBox");
// Don't forget to add this window to another window and set its other properties
// like position, size, etc. Use the methods you prefer.
mListBox->setPosition( CEGUI::Point(0.05f, 0.1f) );
mListBox->setSize( CEGUI::Size(0.90f, 0.80f) );
// mSomeWindow->addChild(mListBox);

// Set the users selection ability
mListBox->setSelectionMode(CEGUI::MultiColumnList::SelectionMode::RowMultiple);

// Add some column headers
mListBox->addColumn("Column1", 0, 0.10f);
mListBox->addColumn("Column2", 1, 0.25f);
mListBox->addColumn("Column3", 2, 0.25f);
mListBox->addColumn("Column4", 3, 0.45f);

// I don't know why, but you have set the column header widths via this function.
// The Column Header widths are not assumed from the "addColumn" function. Bug?
mListBox->setColumnHeaderWidth(0, 0.10f);
mListBox->setColumnHeaderWidth(1, 0.25f);
mListBox->setColumnHeaderWidth(2, 0.25f);
mListBox->setColumnHeaderWidth(3, 0.45f);


Note these lines in the code:

// I don't know why, but you have set the column header widths via this function.
// The Column Header widths are not assumed from the "addColumn" function. Bug?
mListBox->setColumnHeaderWidth(0, 0.10f);
mListBox->setColumnHeaderWidth(1, 0.25f);
mListBox->setColumnHeaderWidth(2, 0.25f);
mListBox->setColumnHeaderWidth(3, 0.45f);

If you don't set the column header widths with the setColumnHeaderWidth() method then the columns will appear to be stacked on top of one another. This may be a bug in the library. The numbers I used for the widths are arbitrary. You can make them anything you like.

!! WARNING !! Take note that you should not follow each addColumn() with a setColumnHeaderWidth(). Create all the columns first and then set the column widths. Not following this will yield unreliable column size results.

In other words DO NOT DO THIS

// Add some column headers
mListBox->addColumn("Column1", 0, 0.10f);
mListBox->setColumnHeaderWidth(0, 0.10f);
mListBox->addColumn("Column2", 1, 0.25f);
mListBox->setColumnHeaderWidth(1, 0.25f);
mListBox->addColumn("Column3", 2, 0.25f);
mListBox->setColumnHeaderWidth(2, 0.25f);
mListBox->addColumn("Column4", 3, 0.45f);
mListBox->setColumnHeaderWidth(3, 0.45f);