Displaying Properties with Labels

Example object can be downloaded here.

This post will give you a heads-up about accessing and displaying property data with labels.
In all building elements of ARCHICAD, the Categories and Properties list can be found on the bottom-last panel of the settings dialogs:
ac_catandproppanel_ac20

This data has a tree-like structure, with many layers of information. Some new requests have been introduced in ARCHICAD 20 to support access to this information from within GDL objects:

  • REQUEST for “Property_Name”
  • REQUEST for “Properties_Of_Parent”
  • REQUEST for “Property_Value_Of_Parent”

Using a combination of these and the new ui_custom_popup_infield command, a label can handle the task.

This label is capable of the following features:

  • option for selecting a property of the parent object, using the interface script only, storing the ID of the selected property in "myProperty" string parameter
  • displaying data (type/group/name/value) belonging to the selected property item in 2D (using text2 in 2D for simplicity)
  • giving feedback information on the interface

prolabelui

While the chosen property’s identifier can be stored in a parameter, make sure you never try to save the property’s value as a parameter.

Getting the available properties and creating the infield on the UI

As properties can change without changing the label or the labeled element itself, we only use the UI script for getting information about the available properties. Parameter script is not needed for dealing with properties, but all elements need graphic UI to be able to handle properties.

As a first step, we need to get the details of all available properties with a request:

dim _parentProperties[]
n = REQUEST ("Properties_Of_Parent", "", _parentProperties)

_parentProperties is a single array, a successful request fills all the id/type/group/name information into it, in the following structure: [Id1, TypeName1, GroupName1, PropertyName1, Id2, TypeName2, GroupName2, PropertyName2, ... Idn, TypeNamen, GroupNamen, PropertyNamen]

Before creating the infield, we should create a “display string” which will be shown as a value on the ui_custom_popup_infield. You can read more about the possible usages of this infield here. This can be done with the “Property_Name” request – as it returns the name, type and group of a property. With the results you can create any display strings you want.

Finally, we need to use the ui_custom_popup_infield. It is quite easy, as we can simply use the _parentProperties array as the possible value list:

ui_custom_popup_infield "myProperty", 
	70, 30, 370, 20, 	! X Position, Y Position, Width, Height
	1, 			! Store Hidden ID
	3,  			! Tree Depth
	1,   			! Grouping Method
	_displayName,   	! Selected Value Description: same as the ID
	_parentProperties

The user can select the property from the tree, and its ID will be stored as a parameter value. In the 2d script, we can use that to request and display the property and its value on the floorplan.

Display the property information and its value in 2d script

As we have a stored property ID, we can get its type/group/name same way we did it in the UI script, using the “Property_Name” request. The more tricky part of the script is getting and formatting the property values – as there can be more than one value for a property, and it is not always a string.

In the example label, a double loop takes care of checking and concatenating all values to a simple string. In this loop we used a subroutine to do the value conversions to strings.

In ARCHICAD 20, there is no option for the user to create 2 dimensional arrays as property values – but later on, if there will be a feature for that, this script will work properly without further changes. It would be possible to check the values of _dim1 and _dim2, and create many if-s, but this double loop is way more reliable.

_valueString = "Value: "
dim _propertyValues[][]
_dim1 = 0
_dim2 = 0
n = REQUEST ("Property_Value_Of_Parent", myProperty, _type, _dim1, _dim2, _propertyValues)

if n then
	! change zeros to ones
	! it is easier to handle all possible arrays in a double loop
	if _dim1  = 0 then _dim1 = 1	
	if _dim2  = 0 then _dim2 = 1

	for ii = 1 to _dim1
		for jj = 1 to _dim2
			if (ii + jj) > 2 then _valueString = _valueString + "; "

			if _type = 4 then ! Type is string - no conversion needed
				_stringPropValue = _propertyValues[jj][ii]
			else	! bool, real, integer types - conversion needed to string
				_valueToConvert = _propertyValues[jj][ii]
				gosub "convertToString"
			endif
			_valueString = _valueString + _stringPropValue
		next jj
	next ii
endif
! ==============================================================================
"convertToString":
! ==============================================================================
! input:
!    - _valueToConvert
!    - _type
! output:
!    - _stringPropValue
! ==============================================================================
	_stringPropValue = ""

	if _type = 3 then		! Real number to string
		_stringPropValue = str ("%.2", _valueToConvert)
	endif

	if _type = 2 then		! Integer to string
		_stringPropValue = str ("%.0", _valueToConvert)
	endif

	if _type = 1 then		! Boolean to string
		if _valueToConvert = 1 then
			_stringPropValue = `True`
		else
			_stringPropValue = `False`
		endif
	endif
return