' ***********************************************************************
' Author : Elektro
' Last Modified On : 11-09-2014
' ***********************************************************************
' <copyright file="ElektroShape.vb" company="Elektro Studios">
' Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************
#Region " Imports "
Imports System.ComponentModel
Imports System.Drawing.Drawing2D
Imports System.Drawing.Text
#End Region
''' <summary>
''' A custom shape control.
''' </summary>
Public Class ElektroShape : Inherits Control
#Region " Properties "
#Region " Visible "
''' <summary>
''' Gets the default size of the control.
''' </summary>
''' <value>The default size.</value>
Protected Overrides ReadOnly Property DefaultSize As Size
Get
Return New Size(100I, 100I)
End Get
End Property
''' <summary>
''' Gets or sets the shape figure.
''' </summary>
''' <value>The shape figure.</value>
<Browsable(True)>
<EditorBrowsable(EditorBrowsableState.Always)>
<Category("Figure")>
<Description("Indicates the shape figure.")>
Public Property Figure As Figures
Get
Return Me._Figure
End Get
Set(ByVal value As Figures)
Me._Figure = value
MyBase.Refresh()
End Set
End Property
''' <summary>
''' The shape figure.
''' </summary>
Private _Figure As Figures = Figures.Circle
''' <summary>
''' Gets or sets a value indicating whether this <see cref="ElektroShape"/> is draggable.
''' </summary>
''' <value><c>true</c> if draggable; otherwise, <c>false</c>.</value>
<Browsable(True)>
<EditorBrowsable(EditorBrowsableState.Always)>
<Category("Figure")>
<Description("Determines whether this control is draggable.")>
Public Property Draggable As Boolean
Get
Return Me._Draggable
End Get
Set(ByVal value As Boolean)
Me._Draggable = value
End Set
End Property
''' <summary>
''' A value indicating whether this <see cref="ElektroShape"/> is draggable.
''' </summary>
Private _Draggable As Boolean = False
''' <summary>
''' Gets or sets the inner color of this <see cref="ElektroShape"/>.
''' </summary>
''' <value>The inner color of this <see cref="ElektroShape"/>.</value>
<Browsable(True)>
<EditorBrowsable(EditorBrowsableState.Always)>
<Category("Figure")>
<Description("The inner color of this shape.")>
Public Property InnerColor As Color
Get
Return Me._InnerColor
End Get
Set(ByVal value As Color)
Me._InnerColor = value
MyBase.Refresh()
End Set
End Property
''' <summary>
''' The inner color of this <see cref="ElektroShape"/>.
''' </summary>
Private _InnerColor As Color = Control.DefaultBackColor
''' <summary>
''' Gets or sets the border color of this <see cref="ElektroShape"/>.
''' </summary>
''' <value>The border color of this <see cref="ElektroShape"/>.</value>
''' <PermissionSet>
''' <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
''' </PermissionSet>
<Browsable(True)>
<EditorBrowsable(EditorBrowsableState.Always)>
<Category("Figure")>
<Description("The border color of this shape.")>
Public Property BorderColor As Color
Get
Return Me._BorderColor
End Get
Set(ByVal value As Color)
Me._BorderColor = value
Me.DoPaint()
End Set
End Property
''' <summary>
''' The border color of this <see cref="ElektroShape"/>.
''' </summary>
Private _BorderColor As Color = Control.DefaultForeColor
''' <summary>
''' Gets or sets the border width of this <see cref="ElektroShape"/>.
''' </summary>
''' <value>The border width of this <see cref="ElektroShape"/>.</value>
<Browsable(True)>
<EditorBrowsable(EditorBrowsableState.Always)>
<Category("Figure")>
<Description("The border width of this figure.")>
Public Property BorderWidth As Integer
Get
Return Me._BorderWidth
End Get
Set(ByVal value As Integer)
Me._BorderWidth = value
Me.DoPaint()
End Set
End Property
''' <summary>
''' The border width of the this <see cref="ElektroShape"/>.
''' </summary>
Private _BorderWidth As Integer = 5I
''' <summary>
''' Gets or sets the interpolation mode of this <see cref="ElektroShape"/>.
''' </summary>
''' <value>The circle's interpolation mode.</value>
<Browsable(True)>
<EditorBrowsable(EditorBrowsableState.Always)>
<Category("Quality")>
<Description("The interpolation mode of this shape.")>
Public Property InterpolationMode As InterpolationMode
Get
Return Me._InterpolationMode
End Get
Set(ByVal value As InterpolationMode)
Me._InterpolationMode = value
Me.DoPaint()
End Set
End Property
''' <summary>
''' The interpolation mode of this <see cref="ElektroShape"/>.
''' </summary>
Private _InterpolationMode As InterpolationMode = Drawing2D.InterpolationMode.Default
''' <summary>
''' Gets or set a value specifying how pixels are offset during rendering this <see cref="ElektroShape"/>.
''' </summary>
''' <value>The circle's pixel offset mode.</value>
<Browsable(True)>
<EditorBrowsable(EditorBrowsableState.Always)>
<Category("Quality")>
<Description("A value specifying how pixels are offset during rendering this shape.")>
Public Property PixelOffsetMode As PixelOffsetMode
Get
Return Me._PixelOffsetMode
End Get
Set(ByVal value As PixelOffsetMode)
Me._PixelOffsetMode = value
Me.DoPaint()
End Set
End Property
''' <summary>
''' A value specifying how pixels are offset during rendering this <see cref="ElektroShape"/>.
''' </summary>
Private _PixelOffsetMode As PixelOffsetMode = Drawing2D.PixelOffsetMode.Default
''' <summary>
''' Gets or sets the rendering quality of this <see cref="ElektroShape"/>.
''' </summary>
''' <value>The circle's smoothing mode.</value>
<Browsable(True)>
<EditorBrowsable(EditorBrowsableState.Always)>
<Category("Quality")>
<Description("The rendering quality of this shape.")>
Public Property SmoothingMode As SmoothingMode
Get
Return Me._SmoothingMode
End Get
Set(ByVal value As SmoothingMode)
Me._SmoothingMode = value
Me.DoPaint()
End Set
End Property
''' <summary>
''' The rendering quality of this <see cref="ElektroShape"/>.
''' </summary>
Private _SmoothingMode As SmoothingMode = Drawing2D.SmoothingMode.Default
#End Region
#Region " Hidden "
''' <summary>
''' Gets or sets the background color of the control.
''' </summary>
''' <value>The background color of the control.</value>
''' <PermissionSet>
''' <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
''' </PermissionSet>
<Browsable(False)>
<EditorBrowsable(EditorBrowsableState.Never)>
<Bindable(False)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
<Description("The background color of the control.")>
Public Overrides Property BackColor() As Color
Get
Dim currentColor As Color = Color.White
If MyBase.Parent IsNot Nothing Then
currentColor = MyBase.Parent.BackColor
End If
Return currentColor
End Get
Set(ByVal Value As Color)
MyBase.BackColor = Value
End Set
End Property
''' <summary>
''' Gets or sets the foreground color of the control.
''' </summary>
''' <value>The foreground color of the control.</value>
''' <PermissionSet>
''' <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
''' </PermissionSet>
<Browsable(False)>
<EditorBrowsable(EditorBrowsableState.Never)>
<Bindable(False)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
<Description("The foreground color of the control.")>
Public Overrides Property ForeColor As Color
Get
Return MyBase.ForeColor
End Get
Set(ByVal value As Color)
MyBase.ForeColor = value
End Set
End Property
''' <summary>
''' Gets or sets the text associated with this control.
''' </summary>
''' <value>The text associated with this control.</value>
<Browsable(False)>
<EditorBrowsable(EditorBrowsableState.Never)>
<Bindable(False)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
<Category("Figure")>
<Description("The text associated with this control.")>
Public Overrides Property Text As String
Get
Return MyBase.Text
End Get
Set(value As String)
MyBase.Text = value
End Set
End Property
''' <summary>
''' Gets or sets the rendering mode for text associated with this <see cref="ElektroShape"/>.
''' </summary>
''' <value>The circle's text rendering hint.</value>
<Browsable(False)>
<EditorBrowsable(EditorBrowsableState.Never)>
<Category("Quality")>
<Description("The rendering mode for text associated with this control.")>
Public Property TextRenderingHint As TextRenderingHint
Get
Return Me._TextRenderingHint
End Get
Set(ByVal value As TextRenderingHint)
Me._TextRenderingHint = value
Me.DoPaint()
End Set
End Property
''' <summary>
''' The rendering mode for text associated with this <see cref="ElektroShape"/>.
''' </summary>
Private _TextRenderingHint As TextRenderingHint = Drawing.Text.TextRenderingHint.SystemDefault
#End Region
#End Region
#Region " Miscellaneous Objects "
''' <summary>
''' The draggable information to drag the control.
''' </summary>
Private Property draggableInfo As DragInfo = DragInfo.Empty
#End Region
#Region " Enumerations "
''' <summary>
''' Contains the default figure designs.
''' </summary>
Public Enum Figures As Integer
''' <summary>
''' Circle figure.
''' </summary>
Circle = 0I
''' <summary>
''' Square figure.
''' </summary>
Square = 1I
''' <summary>
''' Triangle figure.
''' </summary>
Triangle = 2I
End Enum
#End Region
#Region " Types "
''' <summary>
''' Maintains information about a draggable operation.
''' </summary>
Private NotInheritable Class DragInfo
#Region " Properties "
''' <summary>
''' Gets or sets the initial mouse coordinates.
''' </summary>
''' <value>The initial mouse coordinates.</value>
Friend Property InitialMouseCoords As Point = Point.Empty
''' <summary>
''' Gets or sets the initial location.
''' </summary>
''' <value>The initial location.</value>
Friend Property InitialLocation As Point = Point.Empty
''' <summary>
''' Represents a <see cref="T:DragInfo"/> that is <c>Nothing</c>.
''' </summary>
''' <value><c>Nothing</c></value>
Friend Shared ReadOnly Property Empty As DragInfo
Get
Return Nothing
End Get
End Property
#End Region
#Region " Constructors "
''' <summary>
''' Initializes a new instance of the <see cref="DragInfo"/> class.
''' </summary>
''' <param name="mouseCoordinates">The current mouse coordinates.</param>
''' <param name="location">The current location.</param>
Public Sub New(ByVal mouseCoordinates As Point, ByVal location As Point)
Me.InitialMouseCoords = mouseCoordinates
Me.InitialLocation = location
End Sub
#End Region
#Region " Public Methods "
''' <summary>
''' Return the new location.
''' </summary>
''' <param name="mouseCoordinates">The current mouse coordinates.</param>
''' <returns>The new location.</returns>
Public Function NewLocation(ByVal mouseCoordinates As Point) As Point
Return New Point(InitialLocation.X + (mouseCoordinates.X - InitialMouseCoords.X),
InitialLocation.Y + (mouseCoordinates.Y - InitialMouseCoords.Y))
End Function
#End Region
End Class
#End Region
#Region " Constructors "
''' <summary>
''' Initializes a new instance of the <see cref="ElektroShape"/> class.
''' </summary>
Private Sub New()
Me.New(Figures.Circle)
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="ElektroShape"/> class.
''' </summary>
''' <param name="figure">The shape figure.</param>
Public Sub New(ByVal figure As Figures)
With Me
.DoubleBuffered = True
_Figure = figure
End With
End Sub
#End Region
#Region " Overriden Events "
''' <summary>
''' Raises the <see cref="E:System.Windows.Forms.Control.MouseDown"/> event.
''' </summary>
''' <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
MyBase.OnMouseDown(e)
Me.StartDrag()
End Sub
''' <summary>
''' Raises the <see cref="E:System.Windows.Forms.Control.MouseMove"/> event.
''' </summary>
''' <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
MyBase.OnMouseMove(e)
Me.Drag()
End Sub
''' <summary>
''' Raises the <see cref="E:System.Windows.Forms.Control.MouseUp"/> event.
''' </summary>
''' <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
Protected Overrides Sub OnMouseUp(e As MouseEventArgs)
MyBase.OnMouseUp(e)
Me.StopDrag()
End Sub
''' <summary>
''' Raises the <see cref="E:System.Windows.Forms.Control.Paint"/> event.
''' </summary>
''' <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs"/> that contains the event data.</param>
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
With e.Graphics
.InterpolationMode = Me._InterpolationMode
.PixelOffsetMode = Me._PixelOffsetMode
.SmoothingMode = Me._SmoothingMode
' .TextRenderingHint = Me._TextRenderingHint
Select Case Me._Figure
Case Figures.Circle
Me.DrawCircle(e.Graphics)
Case Figures.Square
Me.DrawSquare(e.Graphics)
Case Figures.Triangle
Me.DrawTriangle(e.Graphics)
End Select ' Me._Figure
End With ' e.Graphics
MyBase.OnPaint(e)
End Sub
#End Region
#Region " Private Methods "
#Region " Drag "
''' <summary>
''' Initializes a drag operation.
''' </summary>
Private Sub StartDrag()
If (Me._Draggable) Then
Me.draggableInfo = New DragInfo(MousePosition, MyBase.Location)
End If
End Sub
''' <summary>
''' Drags the control.
''' </summary>
Private Sub Drag()
If (Me._Draggable) AndAlso (Me.draggableInfo IsNot DragInfo.Empty) Then
MyBase.Location = New Point(Me.draggableInfo.NewLocation(MousePosition))
End If
End Sub
''' <summary>
''' Destroys a drag operation.
''' </summary>
Private Sub StopDrag()
Me.draggableInfo = DragInfo.Empty
End Sub
#End Region
#Region " Paint "
''' <summary>
''' Raises the <see cref="E:System.Windows.Forms.Control.Paint"/> event for the specified control.
''' </summary>
Private Sub DoPaint()
Using g As Graphics = MyBase.CreateGraphics
MyBase.InvokePaint(Me, New PaintEventArgs(g, MyBase.ClientRectangle))
End Using
End Sub
''' <summary>
''' Gets a <see cref="System.Drawing.Rectangle"/> with the bounds fixed according to the specified <see cref="System.Drawing.Pen.Width"/>.
''' </summary>
''' <param name="pen">The <see cref="System.Drawing.Pen"/>.</param>
''' <returns>The <see cref="System.Drawing.Rectangle"/> with the bounds fixed.</returns>
Private Function GetFigueRectangle(ByVal pen As Pen) As Rectangle
Return New Rectangle With
{
.x = 0.0F + (pen.Width / 2.0F),
.y = 0.0F + (pen.Width / 2.0F),
.width = (CSng(MyBase.Width) - pen.Width),
.height = (CSng(MyBase.Height) - pen.Width)
}
End Function
''' <summary>
''' Draws a circle on the specified <see cref="System.Drawing.Graphics"/> object.
''' </summary>
''' <param name="g">The <see cref="System.Drawing.Graphics"/> object to paint.</param>
Private Sub DrawCircle(ByRef g As Graphics)
With g
Using pen As New Pen(Me._BorderColor, Me._BorderWidth)
Dim rect As Rectangle = Me.GetFigueRectangle(pen)
If Not Me._InnerColor = Color.Transparent Then
' Fill circle background.
Using brush As New SolidBrush(Me._InnerColor)
.FillEllipse(brush, rect)
End Using
End If ' Not Me._InnerColor = Color.Transparent
' Draw the circle figure.
.DrawEllipse(pen, rect)
End Using ' pen As New Pen(Me._BorderColor, Me._BorderWidth)
End With ' g
End Sub
''' <summary>
''' Draws an square on the specified <see cref="System.Drawing.Graphics"/> object.
''' </summary>
''' <param name="g">The <see cref="System.Drawing.Graphics"/> object to paint.</param>
Private Sub DrawSquare(ByRef g As Graphics)
With g
Using pen As New Pen(Me._BorderColor, Me._BorderWidth)
Dim rect As Rectangle = Me.GetFigueRectangle(pen)
If Not Me._InnerColor = Color.Transparent Then
' Fill the square background.
Using brush As New SolidBrush(Me._InnerColor)
.FillRectangle(brush, rect)
End Using
End If ' Not Me._InnerColor = Color.Transparent
' Draw the square figure.
.DrawRectangle(pen, rect)
End Using ' pen As New Pen(Me._BorderColor, Me._BorderWidth)
End With ' g
End Sub
''' <summary>
''' Draws a triangle on the specified <see cref="System.Drawing.Graphics"/> object.
''' </summary>
''' <param name="g">The <see cref="System.Drawing.Graphics"/> object to paint.</param>
Private Sub DrawTriangle(ByRef g As Graphics)
With g
Using pen As New Pen(Me._BorderColor, Me._BorderWidth)
Using path As New GraphicsPath(FillMode.Alternate)
Dim rect As Rectangle = MyBase.ClientRectangle
' Set the triangle path coordinates.
Dim trianglePoints As PointF() =
{
New PointF(CSng(rect.Left + CSng(rect.Width / 2.0F)), CSng(rect.Top + pen.Width)),
New PointF(CSng(rect.Right - pen.Width), CSng(rect.Bottom - (pen.Width / 2.0F))),
New PointF(CSng(rect.Left + pen.Width), CSng(rect.Bottom - (pen.Width / 2.0F))),
New PointF(CSng(rect.Left + CSng(rect.Width / 2.0F)), CSng(rect.Top + pen.Width))
}
path.AddLines(trianglePoints)
path.CloseFigure()
If Not Me._InnerColor = Color.Transparent Then
' Fill the triangle background.
Using brush As New SolidBrush(Me._InnerColor)
.FillPath(brush, path)
End Using
End If ' Not Me._InnerColor = Color.Transparent
' Draw the triangle figure.
.DrawPath(pen, path)
End Using ' path As New GraphicsPath(FillMode.Alternate)
End Using ' pen As New Pen(Me._BorderColor, Me._BorderWidth)
End With ' g
End Sub
#End Region
#End Region
End Class