Proximity Toolkit Events
Presence Events
Presences are represented graphically by the PresenceControl or programmatically by the PresenceBase object. Specializations of the PresenceBase object include:
- ProximitySpace - the root of the data hierarchy representing the room, or active tracking space.
- TrackedPresence - a "subject" that is being tracked within the space, such as a hat, wand, etc.
- Volume - a fixed or semi-fixed feature of the space, such as a piece of furniture.
- DisplayPlane - definition of a display surface within the space.
- CaptureDevice - a fixed or semi-fixed input/output device within the space, such as a webcam, phidget servo, etc.
- PresenceMarker - (advanced) a point that marks a TrackedPresence.
- PresencePointer - (advanced) a vector that marks a pointing or direction feature of a TrackedPresence.
Note that the PresenceControl is only capable of representing TrackedPresence, Volume, DisplayPlane, and CaptureDevice. In order to specify a presence, you must set the PresenceName property to the name of the expected presence, and PresenceType to the expected type. The PresenceType property is of the PresenceType enumeration, which defines values: Presence, Display, Volume, and Device.
Given a ProximitySpace, you can programmatically obtain any of the four main presence types by calling the following methods:
- ProximitySpace.GetPresence (string name)
- ProximitySpace.GetDisplay (string name)
- ProximitySpace.GetVolume (string name)
- ProximitySpace.GetDevice (string name)
PresenceControl provides a single proximity-related event:
- OnUpdated (PresenceBase presence)
From the PresenceBase object, you can manually retrieve any of the proxemic data by using one of the following read-only properties:
- ILocatable ProxemicLocation
- IDirectable ProxemicDirection
- IMovable ProxemicMotion
- IOrientable ProxemicOrientation
- IRotatable ProxemicRotation
Or, for advanced programmers, you can use the following methods to check for and retrieve these data objects and more (including IFixed, IMarker, IPointer, IVisible, etc.):
bool PresenceBase.HasRelationInterface("I[Locatable|Directable|Orientable|Rotatable|Movable]")
object PresenceBase.GetRelationInterface("I[Locatable|Directable|Orientable|Rotatable|Movable]")
Proxemic Relation Events
Whether using the graphical RelationControl or the programmatic RelationPair to generate data about how two presences relate, the principles of the event callbacks are the same. Of course, in the case of the RelationControl, event callbacks are synchronized to the UI thread, while RelationPair events are asynchronous.
The event names are as follows:
- OnLocationUpdated (LocationRelationEventArgs args)
- OnDirectionUpdated (DirectionRelationEventArgs args)
- OnOrientationUpdated (OrientationRelationEventArgs args)
- OnRotationUpdated (RotationRelationEventArgs args)
- OnMotionUpdated (MotionRelationEventArgs args)
- OnCollisionUpdated (CollisionRelationEventArgs args)
- OnPointingUpdated (PointingRelationEventArgs args)
- OnUpdated (RelationEventArgs args)
As a convention, asynchronous event names are marked with an "Asynch" suffix, and synchronous events are not.
Each one of these callbacks receive an arguments object that provides a number of useful pieces of information. For efficiency sake, the toolkit is designed to only generate these arguments when they are needed, as some can require intensive calculations (ie. Collision).
If you create a handler for any one of On[Location|Direction|Orientation|Rotation|Motion|Collision|Pointing]Updated, the RelationControl or RelationPair will automatically generate the arguments required for the callback. However, there will likely be cases where you need information from other relation types than the one you are currently handling. In this case there are several options for ensuring those arguments are being generated, and also several options for accessing them.
Ensuring Arguments are Generated
- Add an empty event handler to the callback that you need information for.
- RECOMMENDED: Use the Monitor property to explicitly set all the arguments you require.
The Monitor property is of type RelationMonitor which is a flags enumeration. This means you can combine multiple values together as so:
RelationMonitor monitor = RelationMonitor.Location | RelationMonitor.Motion | RelationMonitor.Pointing;
This enumeration also contains values for None and All.
In the Winforms library, the RelationControl has a nifty custom dropdown for the property grid that allows you to check off all the monitors that you like. In the WPF library, the RelationControl has a series of boolean properties for setting these flags:
public bool Monitor[Location|Direction|Orientation|Rotation|Motion|Collision|Pointing]
Accessing the Arguments
- Use the Proxemic[Location|Direction|Orientation|Rotation|Motion|Collision|Pointing] properties on the RelationControl or RelationPair. Note that a value of null is returned if the arguments have not been generated.
- Place your program logic in the OnUpdated event, which receives a RelationEventArgs object that contains all of the generated arguments, likewise accessible under Proxemic[Location|Direction|Orientation|Rotation|Motion|Collision|Pointing] properties. Likewise, a value of null is returned if the arguments have not been generated.