In this posting I explain the behavior and rationale behind the Location and Size properties for various Element types. I also explain the purpose of Translation. We will try to incorporate some of this into the User's Guide, with illustrations.
All Elements
For all Elements, Location is the upper-left corner of the coordinates defining that Element. Size is the width and height extending from the upper left corner. Bounds is another way to get or set both Location and Size simultaneously.
Any Element can contain a transformation. You can modify this through the Transformation property, or by changing the Rotation, Shearing, Scaling, or Translation properties. Transformations are discussed in the User’s Guide. The main thing to note here: a transformation of any kind is a temporary change to an Element. A transformation does not affect the Location, Size, or Bounds property of the Element; it only affects the display of the Element.
Because every Element can have a transformation, when you convert coordinates from an Element space to an ancestor space, it is necessary to accumulate and apply all transformations in between those spaces. There are many functions to do this. The most fundamental one is GetElementToAncestorMatrix.
Leaf Elements
A leaf Element derives from LeafElement. Leaf Elements include all non-composite Elements, such as Rectangle, Ellipse, and Polyline.
Setting Location and Size modifies the coordinates in a leaf Element. For a BoundedElement, such as a Rectangle, setting Location and Size modifies an internal field storing the bounds of the Element.
For an Element that contains points, such as a Polyline, setting Location and Size modifies the points within the Element. This is why a Polyline does not serialize the Location or Size property when saved; the Points property contains the same information.
Groups
Groups are lightweight composite Elements. A Group does not contain any intrinsic bounds defining the Group. Instead, the children of a Group completely define the Location and Size of the Group. Location is the upper-left corner of the union of the Bounds of the children; Size is the width and height of the union of the Bounds of the children.
When you set the Location of a Group, it will traverse the children, and modify their Location properties. When you set the Size of a Group, it modifies both the Location and Size of the children.
Because its children define a Group’s Location and Size, a Group will serialize neither Location nor Size when saved. There is no need, as these two properties are implicitly defined.
Pictures
Pictures are composite Elements like Groups, but they are heavier and have more features. Pictures are the fundamental unit of component reuse in VG.net. Pictures are the classes you add to the Toolbox in Visual Studio .NET.
This discussion concerns Sub Pictures, also called child Pictures. When working with a top-level Picture attached to a Canvas, do not be modify the Location and Size, as this may interfere with other operations, such as zooming and panning.
Like a Group, a Sub Picture does not contain any intrinsic bounds defining the Location and Size of the Picture. However, unlike a Group, a Picture has the notion of a default Location and Size. This default Location and Size is the union of the Bounds of the Picture’s children. If you modify the Bounds of any child, the default Location and Size is also modified.
When you change the Location of a Picture, it does not traverse its children and change their Location properties. Instead, an internal transformation matrix is modified within the Picture. This internal matrix is a ScalingTranslation. It records the difference between the default Location and Size, and the Location and Size set by the user.
Why does Picture behave differently from Group? For performance: we believed the Location and Size of a Sub Picture would be modified frequently. It is much faster to modify a single object, the Picture, than to traverse and modify all children recursively.
When you change a Picture Location from the default value, does it modify the Translation property? No, it does not. We could have implemented Location this way, and made the Size property change other transformation properties. However, we wanted to keep Location and Size independent from (orthogonal to) the transformation properties, as this is the behavior of all other Element types. Therefore we decided to use an additional internal translation and scaling to record changes to a Picture Location and Size.
Sometimes this behavior is undesirable. For example, when implementing a Button class, typically you do not wish to scale the Button unequally as it is resized. Instead, you wish to move and resize various components within the Button. To do this, create a class derived from Picture, and override the SetBoundsCore function. To change the bounds perceived by the Button users, also override the GetBoundsCore function. In this way you can avoid the implicit scaling and translation caused by changes to Location and Size. The TransparentButtons sample demonstrates this technique.
We are currently adding features that will enable you to change the default resize behavior of a Picture without overriding SetBoundsCore.
To reset a Picture Location to its default value, use ResetLocation. To determine the transformation matrix from a Picture’s child space to its parent space, use GetChildToParentMatrix. This combined matrix will include the internal translation and scaling caused by changes to the Location and Size properties, as well as any transformation created by changing standard transformation properties (Transformation, Scaling, Shearing, Rotation, Translation). To retrieve only the changes to the standard transformation properties, use the Transformation or Matrix property.
Location and Size of Leaf Elements, Groups, and Pictures
Moderators: Frank Hileman, Anne Szyjan
- Frank Hileman
- Site Admin
- Posts: 1400
- Joined: Sun Jul 25, 2004 8:16 pm
- Location: California
- Contact: