How do I define my own properties for an object?
This lesson shows how to store custom properties in an object, and how to define getProp/setProp handlers to customize behaviour when getting/setting custom properties
Introduction
All objects in LiveCode have properties: built-in properties such as the name, width & height of an object, and custom properties which can be used to store any kind of information associated with that object.
The built-in properties often have an immediate effect on the appearance or behaviour of an object, whereas custom properties require some scripting on behalf of the LiveCode programmer to have an effect.
Setting and Getting Custom Properties
The syntax for accessing custom properties is the same as that used to access built-in properties so it is important to choose names for custom properties that are different from the built-in object properties to avoid confusion.
One common approach to custom property naming is to prefix the names of custom properties with a lowerspace 'c' character. As an example, if we wish to store a name and location within an object as a custom property, we could do the following:
set the cName of field "livecode" to "LiveCode Ltd."
set the cLocation of field "livecode" to "Edinburgh"
The "name" and "location" properties are built-in and common to all objects, so cannot be used as the names of our custom properties.
getProp and setProp Handlers
If we want our custom properties to be more than just static collections of data, we need a way to script how an object behaves when these properties are accessed. This is done by defining getProp
and setProp
handlers for each custom property.
getProp
Using a getProp handler allows us to define a custom property as a function which returns a value computed at the time the property is requested.
To define a getProp handler for a property, the following syntax is used:
getProp <propertyName>
/*
the script which calculates
the value to return goes here
...
*/
return <propertyValue>
end <propertyName>
The following code shows an example of a getProp handler for a "longestline" property, which gives the longest line in a field or other text-containing object:
getProp longestLine
local tLongestLine, tLongestLength, tLineLength
put 0 into tLongestLength
repeat for each line tLine in the text of me
put the number of chars in tLine into tLineLength
if tLineLength > tLongestLength then
put tLineLength into tLongestLength
put tLine into tLongestLine
end if
end repeat
return tLongestLine
end longestLine
setProp
By adding setProp handlers to an object we can reduce complex operations to simple one-line scripts. As an example, lets consider rotating a polygon through a given angle. The built-in angle property has no effect on freehand polygons, but we can use the utility function revRotatePoly. revRotatePoly modifies the points of a polygon in such a way that repeated uses of the function can deform the points of our polygon, so we also need to save the points of the polygon and restore these original points before rotation. To simplify this process we can encapsulate this behaviour within a setProp handler for a new property "rotation" that acts as an angle property for freehand polygons:
setProp rotation pValue
local tPoints, tLoc
lock screen
put the loc of me into tLoc
if the cOldPoints of me is empty then
// save the points before rotation
put the points of me into tPoints
set the cOldPoints of me to tPoints
else
// restore the saved points
put the cOldPoints of me into tPoints
set the points of me to tPoints
end if
if pValue is 0 or pValue is empty then
set the cOldPoints of me to empty
else
revRotatePoly (the long id of me), pValue
end if
set the loc of me to tLoc
unlock screen
end rotation
We can now use this property to rotate our polygon simply by setting the rotation property.
Note that defining a getProp or setProp handler for a custom property bypasses LiveCode's normal mechanism for storing custom properties, however we can still store them as normal within the property handler itself. When a property handler for a particular custom property attempts to access that same custom property, rather than invoking the property handler in a infinite recursive loop, the custom property is accessed directly, rather than through the handler.
This example shows how to access and modify a custom property which is otherwise "masked" by the getProp handler:
getProp nextValue
local tNextValue
// this access of nextValue will not result
// in the getProp handler being called again
put the nextValue of me into tNextValue
if tNextValue is empty then put 1 into tNextValue
set the nextValue of me to tNextValue + 1
return tNextValue
end nextValue
With this handler, every time we get the nextValue of an object, the stored property is incremented so that the next time we get the nextValue it will have increased by 1.
0 Comments
Add your comment