Learn to manage BIM workflows and create professional Archicad templates with the BIM Manager Program.

Archicad C++ API
About Archicad add-on development using the C++ API.
SOLVED!

Property Manager style ListBox

LaszloHatvani
Contributor

Is there any ListBox kind of class which handles grouped lists like the Property Manager?

 

Features: closeable groups, group names / headlines (one row one text through multiple columns)

1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Miklos Vegh
Graphisoft
Graphisoft

I think there is no general usable solution for such a listbox, so you need to implement it for yourself. You need a data structure that describes the groups and the items in the group, and then build up a listbox with the data.

The group items accept mouse click (expand/collapse) and the observer handles them by inserting/removing the items of the group to/from the listbox. They will be slightly different than the other normal list items.

Displaying content through multiple columns is easily achievable. There is an 'owner drawn' flag on listbox items that can be enabled for each list item individually:

void	SetItemOwnerDrawFlag (short listItem, bool isOwnerDrawn);

You should enable this flag on the group items. This way for these group-rows the following happens: the listbox control draws the content of each column of that row, then the following notification is sent to the listbox observer:

virtual void	ListBoxItemUpdate (const ListBoxItemUpdateEvent& ev);

The notificaton handler function receives the drawing context of the whole list row in the event argument. It can draw anything on the drawing context independently of column boundaries.

Here is an example for a listbox item update function that draws a text and an icon:

void SampleDialog::ListBoxItemUpdate (const DG::ListBoxItemUpdateEvent& ev)
{
	if (ev.GetSource () == &listBox) {
		short listFont = DGGetItemFont (listBox.GetPanelId (), listBox.GetId ());
		short listItemSize = DG_IS_LARGE;
		if (listFont != DG_IS_DEFAULT)
			listItemSize = listFont & DG_IS_SIZEMASK;
		short listItemStyle = DGListGetItemStyle (listBox.GetPanelId (), listBox.GetId (), ev.GetListItem ());
		short fontType = listItemSize | listItemStyle;

		NewDisplay::ListBoxUpdateEventContext context (ev);
		DG::Utils::DrawText (context, DG::Rect (listBox.GetTabFieldBeginPosition (TextColumnId) + 10, 2, ev.GetWidth () - 2, ev.GetHeight () - 2), 
							 "Text of the group item", fontType, DG_IS_LEFT);
		DG::Rect tabItemRect = DG::Rect (listBox.GetTabFieldBeginPosition (IconColumnId), 0, listBox.GetTabFieldEndPosition (IconColumnId), ev.GetHeight ());
		DG::Utils::DrawIcon (context, tabItemRect, DG::Icon (....));
	}
}

Note: The owner drawn flag can be set not only on individual rows but on columns also, but that is an other feature resulting a different notification.

View solution in original post

2 REPLIES 2

Hi Laszlo,

 

You can almost achieve this with the "Tree View" item type. Only proper group names / headlines through multiple columns I wasn't able to achieve with this item type yet.

 

Best,
Bernd

Solution
Miklos Vegh
Graphisoft
Graphisoft

I think there is no general usable solution for such a listbox, so you need to implement it for yourself. You need a data structure that describes the groups and the items in the group, and then build up a listbox with the data.

The group items accept mouse click (expand/collapse) and the observer handles them by inserting/removing the items of the group to/from the listbox. They will be slightly different than the other normal list items.

Displaying content through multiple columns is easily achievable. There is an 'owner drawn' flag on listbox items that can be enabled for each list item individually:

void	SetItemOwnerDrawFlag (short listItem, bool isOwnerDrawn);

You should enable this flag on the group items. This way for these group-rows the following happens: the listbox control draws the content of each column of that row, then the following notification is sent to the listbox observer:

virtual void	ListBoxItemUpdate (const ListBoxItemUpdateEvent& ev);

The notificaton handler function receives the drawing context of the whole list row in the event argument. It can draw anything on the drawing context independently of column boundaries.

Here is an example for a listbox item update function that draws a text and an icon:

void SampleDialog::ListBoxItemUpdate (const DG::ListBoxItemUpdateEvent& ev)
{
	if (ev.GetSource () == &listBox) {
		short listFont = DGGetItemFont (listBox.GetPanelId (), listBox.GetId ());
		short listItemSize = DG_IS_LARGE;
		if (listFont != DG_IS_DEFAULT)
			listItemSize = listFont & DG_IS_SIZEMASK;
		short listItemStyle = DGListGetItemStyle (listBox.GetPanelId (), listBox.GetId (), ev.GetListItem ());
		short fontType = listItemSize | listItemStyle;

		NewDisplay::ListBoxUpdateEventContext context (ev);
		DG::Utils::DrawText (context, DG::Rect (listBox.GetTabFieldBeginPosition (TextColumnId) + 10, 2, ev.GetWidth () - 2, ev.GetHeight () - 2), 
							 "Text of the group item", fontType, DG_IS_LEFT);
		DG::Rect tabItemRect = DG::Rect (listBox.GetTabFieldBeginPosition (IconColumnId), 0, listBox.GetTabFieldEndPosition (IconColumnId), ev.GetHeight ());
		DG::Utils::DrawIcon (context, tabItemRect, DG::Icon (....));
	}
}

Note: The owner drawn flag can be set not only on individual rows but on columns also, but that is an other feature resulting a different notification.

Didn't find the answer?

Check other topics in this Forum

Back to Forum

Read the latest accepted solutions!

Accepted Solutions

Start a new conversation!