This documentation is for the old version. Go to the latest Graphics Mill docs

Creating Custom Navigators and Rubberbands (Windows Forms)

Graphics Mill for .NET comes with several ready-to-use navigators and rubberbands. They are:

The use of these navigators and rubberbands is described in the Using Navigators and Rubberbands (Windows Forms) topic.

However, in some cases the controls that are shipped with Graphics Mill for .NET are insufficient, and you may want to create your own controller. This is a pretty easy task. Here it will be shown how to create a simple navigator and a simple rubberband.

General Information

When creating your own custom controller (navigator or rubberband), consider the following interfaces that Graphics Mill for .NET provides:

  • INavigator, an empty interface that should be inherited if you create a navigator.
  • IRubberband, an empty interface that should be inherited if you create a rubberband.
  • IUserInputController, an interface that actually contains required members and from which both INavigator and IRubberband inherit.

The IUserInputController controller provides three methods required for each navigator/rubberband. However, there is no need to implement it directly, instead you can inherit from the UserInputController abstract class which contains a partial implementation of the IUserInputController interface. You will need to override only those protected members of this class that are required for your navigator/rubberband.

When your navigator/rubberband is created, you may use it as any other navigator/rubberband of Graphics Mill for .NET.

Implementation examples

Color Picker Navigator

Suppose, you want to implement a navigator that will copy the RGB channel values of the picked pixel to clipboard. To do that you will need to inherit from the UserInputController and override two of its methods:

  • The OnViewerMouseUp(MouseEventArgs) method will do all the work. It will check if the navigator is connected to the bitmap viewer. If yes, it will check if any bitmap is loaded, and then copy the channel values of the picked pixel.
  • The UpdateCursor(Boolean, Point) method sets the cursor, specific for this navigator.

Below is the sample implementation of this ColorPickerNavigator class.

Visual Basic
Public Class ColorPickerNavigator
    Inherits UserInputController
    Implements INavigator

    Sub New()
        'The cursor file should be an embedded resource to be called this way.
        _cursor = New System.Windows.Forms.Cursor(Me.GetType(), _
            "ColorPicker.cur")
    End Sub

    Protected Overrides Sub OnViewerMouseUp(ByVal e As _
        System.Windows.Forms.MouseEventArgs)
        'Get the pixel channel values only if the bitmap is loaded.
        If IsViewerAttached And ViewerHasContent Then
            Dim bitmapViewer As BitmapViewer = CType(Viewer, BitmapViewer)

            'Retrieve the pixel color value.
            Dim color As Aurigma.GraphicsMill.Color = _
                bitmapViewer.Bitmap.GetPixel(e.X, e.Y)

            'The RGB channel values will be displayed, so we convert the
            'colorspace to RGB if needed.
            If color.ColorSpace <> Aurigma.GraphicsMill.ColorSpace.Rgb Then
                color.ConvertColorSpace(Aurigma.GraphicsMill.ColorSpace.Rgb)
            End If

            '...Do something to the color values...
            'For example, read the channel values into a text string and copy
            'it to the clipboard.
            Dim text As String = String.Format("R: {0} G: {1} B: {2}", _
            color.GetChannel32(Aurigma.GraphicsMill.ColorChannel.Red), _
            color.GetChannel32(Aurigma.GraphicsMill.ColorChannel.Green), _
            color.GetChannel32(Aurigma.GraphicsMill.ColorChannel.Blue))
            System.Windows.Forms.Clipboard.SetDataObject(text, True)
        End If
    End Sub

    Protected Overrides Sub UpdateCursor(ByVal isCursorDefault As Boolean, _
        ByVal point As System.Drawing.Point)
        'Display this navigator cursor.
        If isCursorDefault Then
            Viewer.RestoreCursorToDefault()
            Return
        End If
        Viewer.Cursor = _cursor
    End Sub

    Private _cursor As System.Windows.Forms.Cursor
End Class
C#
public class ColorPickerNavigator : UserInputController, INavigator
{
    public ColorPickerNavigator()
    {
        //The cursor file should be an embedded resource to be called this way.
        _cursor = new System.Windows.Forms.Cursor(GetType(), "ColorPicker.cur");
    }

    protected override void OnViewerMouseUp(System.Windows.Forms.MouseEventArgs e)
    {
        //Get the pixel channel values only if the bitmap is loaded.
        if (IsViewerAttached && ViewerHasContent)
        {
            BitmapViewer bitmapViewer = (BitmapViewer)Viewer;

            //Retrieve the pixel color value.
            Color color = bitmapViewer.Bitmap.GetPixel(e.X, e.Y);

            //The RGB channel values will be displayed, so we convert the colorspace
            //to RGB if needed.
            if (color.ColorSpace != ColorSpace.Rgb)
                color.ConvertColorSpace(ColorSpace.Rgb);

            //...Do something to the color values...
            //For example, read the channel values into a text string and copy
            //it to the clipboard.
            string text = String.Format("R: {0} G: {1} B: {2}",
                color.GetChannel32(ColorChannel.Red),
                color.GetChannel32(ColorChannel.Green),
                color.GetChannel32(ColorChannel.Blue));
            System.Windows.Forms.Clipboard.SetDataObject(text, true);
        }
    }

    protected override void UpdateCursor(bool isCursorDefault, System.Drawing.Point point)
    {
        //Display this navigator cursor.
        if (isCursorDefault)
        {
            Viewer.RestoreCursorToDefault();
            return;
        }
        Viewer.Cursor = _cursor;
    }

    private System.Windows.Forms.Cursor _cursor;
}

Text Rubberband

Another approach to navigator/rubberband implementation is inheritance from an existing navigator/rubberband class. To demonstrate this method, we will create the TextRubberband class. This class will inherit from the RectangleRubberband class and use its functionality to do almost everything.

The only method you need to override is the OnViewerDoubleBufferPaint(PaintEventArgs) method. And even in this case, most of the job will be done by its base implementation. You will only need to add code lines for drawing text. Also, you will need to add a couple of properties to manipulate text settings. Here is how this class can be implemented.

Visual Basic
Public Class TextRubberband
    Inherits RectangleRubberband

    Sub New()
        MyBase.New()

        'Set the text that will be displayed and its properties.
        _text = ""
        _font = New System.Drawing.Font(System.Drawing.FontFamily.GenericSansSerif, _
            12.0F)
        _brush = New System.Drawing.SolidBrush(System.Drawing.Color.Black)
    End Sub

    Sub New(ByVal text As String)
        MyBase.New()

        _text = text
        _font = New System.Drawing.Font(System.Drawing.FontFamily.GenericSansSerif, _
            12.0F)
        _brush = New System.Drawing.SolidBrush(System.Drawing.Color.Black)
    End Sub

    'Properties to manipulate rubberband settings
    Property Text() As String
        Get
            Return _text
        End Get
        Set(ByVal Value As String)
            _text = Value
        End Set
    End Property

    Property Font() As System.Drawing.Font
        Get
            Return _font
        End Get
        Set(ByVal Value As System.Drawing.Font)
            _font = Value
        End Set
    End Property

    Property Color() As System.Drawing.Color
        Get
            Return _brush.Color
        End Get
        Set(ByVal Value As System.Drawing.Color)
            _brush.Color = Value
        End Set
    End Property

    'The only method that needs to be overriden is used to draw text.
    Protected Overrides Sub OnViewerDoubleBufferPaint(ByVal e As _
        System.Windows.Forms.PaintEventArgs)
        'The base implementation is called to draw the rubberband itself.
        MyBase.OnViewerDoubleBufferPaint(e)
        If Not IsEmpty Then
            e.Graphics.DrawString(_text, _font, _brush, MyBase.Rectangle.X, _
                MyBase.Rectangle.Y)
        End If
    End Sub

    Private _text As String
    Private _font As System.Drawing.Font
    Private _brush As System.Drawing.SolidBrush
End Class
C#
public class TextRubberband : RectangleRubberband
{
    public TextRubberband() : base()
    {
        //Set the text that will be displayed and its properties.
        _text = "";
        _font = new System.Drawing.Font(System.Drawing.FontFamily.GenericSansSerif, 12f);
        _brush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
    }

    public TextRubberband(string text) : base()
    {
        _text = text;
        _font = new System.Drawing.Font(System.Drawing.FontFamily.GenericSansSerif, 12f);
        _brush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
    }

    //Properties to manipulate rubberband settings.
    public string Text
    {
        get
        {
            return _text;
        }

        set
        {
            _text = value;
        }
    }

    public System.Drawing.Font Font
    {
        get
        {
            return _font;
        }
        set
        {
            _font = value;
        }
    }

    public System.Drawing.Color Color
    {
        get
        {
            return _brush.Color;
        }
        set
        {
            _brush.Color = value;
        }
    }

    //The only method that needs to be overriden is used to draw text.
    protected override void OnViewerDoubleBufferPaint(System.Windows.Forms.PaintEventArgs e)
    {
        //The base implementation is called to draw the rubberband itself.
        base.OnViewerDoubleBufferPaint (e);
        if (!IsEmpty)
            e.Graphics.DrawString(_text, _font, _brush, base.Rectangle);
    }

    private string _text;
    private System.Drawing.Font _font;
    private System.Drawing.SolidBrush _brush;
}

Note that this is not a real-world sample, this implementation is provided for demonstrational purposes only. If you want to get the functionality of this rubberband, use the VObjectsRubberband class, which provides much richer functionality on text adding and manipulation.

See Also

Reference

Manual