Difference between revisions of "MultiColumnList"

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Jump to: navigation, search
m (Reverted edit of Buba50, changed back to last version by Jamhap)
 
(2 intermediate revisions by 2 users not shown)
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.
+
{{VersionBadge|0.4}} {{VersionBadge|0.5}} {{VersionBadge|0.6}}
  
 
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.
 
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.
Line 17: Line 17:
 
<pre>
 
<pre>
 
// Get the CEGUI Window Manager
 
// Get the CEGUI Window Manager
CEGUI::WindowManager *mWinMgr = CEGUI::WindowManager::getSingletonPtr();
+
CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
  
 
// Create the CEGUI MultiColumnList window
 
// Create the CEGUI MultiColumnList window
CEGUI::MultiColumnList *mListBox = (CEGUI::MultiColumnList *)mWinMgr->createWindow(
+
CEGUI::MultiColumnList *mListBox = static_cast<CEGUI::MultiColumnList *>(wmgr->createWindow("TaharezLook/MultiColumnList", "MyListBox"));
(CEGUI::utf8*)CEGUILOOK"/MultiColumnList", (CEGUI::utf8*)"MyListBox");
+
 
// Don't forget to add this window to another window and set its other properties
 
// Don't forget to add this window to another window and set its other properties
 
// like position, size, etc. Use the methods you prefer.
 
// like position, size, etc. Use the methods you prefer.
Line 36: Line 35:
 
mListBox->addColumn("Column3", 2, 0.25f);
 
mListBox->addColumn("Column3", 2, 0.25f);
 
mListBox->addColumn("Column4", 3, 0.45f);
 
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);
 
</pre>
 
 
 
Note these lines in the code:
 
 
<pre>
 
// 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);
 
</pre>
 
 
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'''
 
<pre>
 
// 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);
 
 
</pre>
 
</pre>
  
Line 85: Line 48:
 
   unsigned int mRow = mListBox->addRow();
 
   unsigned int mRow = mListBox->addRow();
  
   // Remember, each column is a 'ListboxTextitem' so we need to
+
   // Remember, each column is a 'ListboxTextItem' so we need to
 
   // create a new instance for each column.
 
   // create a new instance for each column.
  
 
   // Column1
 
   // Column1
   // Create our ListboxTextItem instance...
+
   // Create our ListboxTextItem instance.
   CEGUI::ListboxTextItem* item = new CEGUI::ListboxTextItem((CEGUI::utf8*)c1, 0);
+
   CEGUI::ListboxTextItem* item = new CEGUI::ListboxTextItem(c1, 0);
 
   // Note that in 'setItem' we specify '0' for the index/column we want this
 
   // Note that in 'setItem' we specify '0' for the index/column we want this
 
   // ListboxTextItem to be attached too.
 
   // ListboxTextItem to be attached too.
 
   mListBox->setItem(item, 0, mRow);
 
   mListBox->setItem(item, 0, mRow);
 
   // Should it be selected? I know this appears weird but yes you can have columns be
 
   // 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  
+
   // selected or not selected. In other words, its not Row based, its Column based  
   // selection. Why? more options and flexibilty!
+
   // selection for more options and flexibility!
 
   item->setSelected(isSelected);
 
   item->setSelected(isSelected);
 
   // Don't forget to set the selection brush or your item won't get highlighted.
 
   // Don't forget to set the selection brush or your item won't get highlighted.
   item->setSelectionBrushImage( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MultiListSelectionBrush");
+
   item->setSelectionBrushImage( "TaharezLook", "MultiListSelectionBrush");
 
   // You could attach some data to this column that is important to you by
 
   // 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
 
   // using the 'setUserData' function. Each column could point to a different
Line 106: Line 69:
  
 
   // Column2
 
   // Column2
   item = new CEGUI::ListboxTextItem((CEGUI::utf8*)c2, 0);
+
   item = new CEGUI::ListboxTextItem(c2, 0);
 
   mListBox->setItem(item, 1, mRow);
 
   mListBox->setItem(item, 1, mRow);
 
   item->setSelected(isSelected);
 
   item->setSelected(isSelected);
   item->setSelectionBrushImage( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MultiListSelectionBrush");
+
   item->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
  
 
   // Column3
 
   // Column3
   item = new CEGUI::ListboxTextItem((CEGUI::utf8*)c3, 0);
+
   item = new CEGUI::ListboxTextItem(c3, 0);
 
   mListBox->setItem(item, 2, mRow);
 
   mListBox->setItem(item, 2, mRow);
 
   item->setSelected(isSelected);
 
   item->setSelected(isSelected);
   item->setSelectionBrushImage( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MultiListSelectionBrush");
+
   item->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
  
 
   //Column4
 
   //Column4
   item = new CEGUI::ListboxTextItem((CEGUI::utf8*)c4, 0);
+
   item = new CEGUI::ListboxTextItem(c4, 0);
 
   mListBox->setItem(item, 3, mRow);
 
   mListBox->setItem(item, 3, mRow);
 
   item->setSelected(isSelected);
 
   item->setSelected(isSelected);
   item->setSelectionBrushImage( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MultiListSelectionBrush");
+
   item->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
  
 
} // addListboxItem
 
} // addListboxItem
Line 128: Line 91:
  
  
Now, somewhere in your code, call the ''addListboxItem'' function like this:
+
Somewhere in your code, call the ''addListboxItem'' function like this:
  
 
<pre>
 
<pre>
Line 150: Line 113:
  
 
'''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.
 
'''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.
 
'''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.
 +
 +
[[Category:Tutorials]]

Latest revision as of 16:37, 4 March 2011

Written for CEGUI 0.4


Works with versions 0.4.x (obsolete)

Written for CEGUI 0.5


Works with versions 0.5.x (obsolete)

Written for CEGUI 0.6


Works with versions 0.6.x (obsolete)

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: MultiColumnList ListboxItem ListboxTextItem 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

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

// Get the CEGUI Window Manager
CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();

// Create the CEGUI MultiColumnList window
CEGUI::MultiColumnList *mListBox = static_cast<CEGUI::MultiColumnList *>(wmgr->createWindow("TaharezLook/MultiColumnList", "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);

Adding Data

Now, lets create a method to add data to our MultiColumnList. Review this code:

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(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 for more options and flexibility!
  item->setSelected(isSelected);
  // Don't forget to set the selection brush or your item won't get highlighted.
  item->setSelectionBrushImage( "TaharezLook", "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(c2, 0);
  mListBox->setItem(item, 1, mRow);
  item->setSelected(isSelected);
  item->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");

  // Column3
  item = new CEGUI::ListboxTextItem(c3, 0);
  mListBox->setItem(item, 2, mRow);
  item->setSelected(isSelected);
  item->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");

  //Column4
  item = new CEGUI::ListboxTextItem(c4, 0);
  mListBox->setItem(item, 3, mRow);
  item->setSelected(isSelected);
  item->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");

} // addListboxItem


Somewhere in your code, call the addListboxItem function like this:

  ...
  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);
  ...

You will note that in the above source code I have specified two rows to be highlighted. This is possible because of the

mListBox->setSelectionMode(CEGUI::MultiColumnList::SelectionMode::RowMultiple);

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.

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.