Graphics Mill for .NET contains a module called Vector Objects which allows adding a user interface for vector graphics and multi-layer imaging to Windows Forms applications. Just a few examples of this module usage:
This article gives an overview of the Vector Objects architecture.
Objects provided by this module can be divided into three groups:
Containers are represented by host objects and layers.
The main host object is MultiLayerViewer. It accepts user input and contain a stack of layers.
Layers associated with a particular MultiLayerViewer control are organized in an array (you can access it through the IVObjectHost.Layers property). The order of Layer objects in this array defines the Z-order of displayed layers. The lesser value the layer index equals to, the lower is the layer. Layers can be moved to the front and to the back, locked or made invisible.
The layers contain v-objects (drawing shapes, images, text strings). These v-objects are also organized into an array (you can access it through the Layer.VObjects property) that defines the Z-order of the objects within a particular layer in the same manner as described above.
Another example of the host object is BitmapViewer when it is used with VObjectsRubberband. VObjectsRubberband allows the BitmapViewer control to host any v-object. This way you can add Vector Objects functionality into existing application which is based on the BitmapViewer. An example of using BitmapViewer as a host control can be found in the Using V-objects With the BitmapViewer Control topic.
When you create new application, and if you are going to use Vector Objects features extensively, it is recommended to use MultiLayerViewer instead of BitmapViewer and VObjectsRubberband bundle. MultiLayerViewer was specifically designed and optimized for Vector Objects, for example, it provides a caching mechanism (allows to handle a large number of v-objects without the performance drop). On the contrary, the BitmapViewer + VObjectsRubberband combination is designed just to allow to operate v-objects on the image. If you add too many objects, it will work too slow.
That is why it is recommended to use the BitmapViewer control, only when just a few vector objects are required. Otherwise, it is better to use the MultiLayerViewer control.
Another group of objects comprises of v-objects and designers associated with them.
The v-objects represent the image elements such as:
Each v-object implements the IVObject interface. A list of available v-objects is presented below.
Designers are helper objects that are intermediate between the container and the corresponding v-object. The designers handle the user input forwarded from the host control and manipulate with v-objects according to this input (e.g. move, resize, rotate, etc).
Each designer implements the IDesigner interface.
Interaction between the user and the MultiLayerViewer control is illustrated by the following figure:
Fig. 1. Interaction between the user and the control
That is, when the user sends some input to the container control (e.g. presses down a mouse button somewhere inside the viewer area), this input is first handled by the control. The container checks if some v-object is currently selected (active). The designer of an active v-object is called the current designer (see the figure above).
If an active v-object exists, the host control carries out the hit test operation to determine whether the input relates to this v-object or not. If yes, the input is forwarded to the current designer which performs an appropriate action (moves the v-object, or, say, resizes it). Otherwise, a special designer, DefaultDesigner, checks whether some other v-object is picked, and makes an appropriate v-object active (the current designer is changed in this case).
If no v-object is selected, the default designer is used. This designer allows to select multiple v-objects.
When multiple v-objects are selected, they can be manipulated as a single object using CompositeVObject. Accordingly, CompositeVObjectEditDesigner is used as a corresponding designer.
Each v-object provides a set of control points. Depending on the state of control points, the appearance and/or position of a v-object may be changed.
For example, a rectangle may be presented with four points - each point means the coordinates of rectangle vertices. When the user changes the position of some of vertex, the rectangle is resized.
In general, Vector Objects module allows you to define control points not only for resize or position change, but for any other kind of operation - rotation, distortion, recolorization, or whatever else you can imagine. These operations are called actions in terms of Vector Objects. Standard v-objects support the following actions:
Polylines and text v-objects support additional actions.
Let's see how it works under the hood. When the control point is modified, the designer of the appropriate v-object calls the DragPoint(Int32, PointF) or ClickPoint(Int32) method of this object passing the index of the clicked point and its new coordinates. V-objects use these methods to change themselves appropriately.
Actions supported by the v-object are listed in the array returned by the SupportedActions property. If you do not want a v-object to support some of actions, you can just set the Enabled property of an appropriate action object returned from this array.
Different actions may have different settings. For example, resize action can have different modes - proportional (the aspect ratio of a v-object is fixed) or free (the aspect ratio of a v-object can be changed). All these settings are accessible through appropriate properties of the action object.
Let's take a look how to configure an action of a v-object. As an example, let's set the resize mode of a resize action to proportional:
'Get the currently selected object Dim vobject As Aurigma.GraphicsMill.WinControls.IControlPointsProvider = _ CType(multiLayerViewer1.CurrentDesigner.VObjects(0), _ Aurigma.GraphicsMill.WinControls.IControlPointsProvider) 'Check if resize is supported by this object If (vobject.SupportedActions.Contains( _ Aurigma.GraphicsMill.WinControls.VObjectAction.Resize)) Then 'Make resize proportional Dim action As Aurigma.GraphicsMill.WinControls.ResizeVObjectAction = _ CType(vobject.SupportedActions.Item( _ Aurigma.GraphicsMill.WinControls.VObjectAction.Resize), _ Aurigma.GraphicsMill.WinControls.ResizeVObjectAction) action.ResizeMode = Aurigma.GraphicsMill.WinControls.ResizeMode.Proportional End If
//Get the currently selected object Aurigma.GraphicsMill.WinControls.IControlPointsProvider vobject = (Aurigma.GraphicsMill.WinControls.IControlPointsProvider) multiLayerViewer1.CurrentDesigner.VObjects[0]; //Check if resize is supported by this object if (vobject.SupportedActions.Contains( Aurigma.GraphicsMill.WinControls.VObjectAction.Resize)) { //Make resize proportional Aurigma.GraphicsMill.WinControls.ResizeVObjectAction action = (Aurigma.GraphicsMill.WinControls.ResizeVObjectAction) vobject.SupportedActions[Aurigma.GraphicsMill.WinControls.VObjectAction.Resize]; action.ResizeMode = Aurigma.GraphicsMill.WinControls.ResizeMode.Proportional; }
As for now, you can use the following v-objects:
Several v-objects can be combined in one composite v-object (CompositeVObject), that allows working with them as with one object.
You can also create custom v-objects by implementing the IVObject interface.
All these v-objects have common properties:
Also, different v-objects have additional specific properties, for example, TextVObject has a font, a text string and a string format.