AdvancedHMI Software

General Category => Open Discussion => Topic started by: rbelknap on October 19, 2015, 11:39:10 AM

Title: Extending ADHMI Controls
Post by: rbelknap on October 19, 2015, 11:39:10 AM
I'd like to add a Label to the Pilotlight Control.

When the color changes it would display a piece of text, ie Open/Close, On/Off, Up/Down, etc.

I'm developing my first ADHMI project and like the looks of the pilot light, and would be using it for various different items.

I've written a lot of VB code over the years, but very few controls, and none in quite some time.

I tried looking for instructions on something like this, but couldn't find anything similar.

Thanks.
Title: Re: Extending ADHMI Controls
Post by: Archie on October 19, 2015, 05:35:02 PM
Modifying controls or writing custom controls can get quite involved. When we give our training, it can take up to 2 weeks of training before people master custom controls.

So let's start with the bare minimum to give you something to start playing with. Right Click the folder AdvancedHMIControls\PurchasedControls and select Add->New Class.

Name the class PilotLightEx and add this code:
Code: [Select]
Public Class PilotLightEx
    Inherits AdvancedHMIControls.PilotLight

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)

        e.Graphics.DrawString("My added Text", Me.Font, Brushes.Black, 5, 5)
    End Sub
End Class

Now build the project and see if you have a PilotLightEx in your ToolBox
Title: Re: Extending ADHMI Controls
Post by: rbelknap on October 20, 2015, 07:53:39 AM
Archie,

I appreciate the help.  This worked well for a start.

Of course I'd like to make most of that into a set of properties/states.

Let me see what I can come up with and get back to you.

I realize it won't be easy, but as I've learned over the years, most things aren't.

Thanks,

Rich
Title: Re: Extending ADHMI Controls
Post by: Archie on October 20, 2015, 08:11:18 AM
If you were able to get that much working, let's take another step. Add this code to your PilotLightEx:
Code: [Select]
    Protected Overrides Sub OnValueChanged(e As EventArgs)
        MyBase.OnValueChanged(e)

        If MyBase.Value = "True" Then
            MyBase.Text = "On"
        Else
            MyBase.Text = "off"
        End If
    End Sub
Title: Re: Extending ADHMI Controls
Post by: rbelknap on October 20, 2015, 09:35:27 AM
I went a bit beyond in playing around.

Here is what I have now.
Code: [Select]

Public Class PilotLightEx
    Inherits AdvancedHMIControls.PilotLight

    Private Textx As Single
    Private Texty As Single

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        Dim myTextSize As New SizeF
        If Me.Value = True Then
            myTextSize = e.Graphics.MeasureString(LightColorOnText, Me.Font)
            CenterText(myTextSize)

            e.Graphics.DrawString(LightColorOnText, Me.Font, Brushes.Black, Textx, Texty)
        Else
            myTextSize = e.Graphics.MeasureString(LightColorOffText, Me.Font)
            CenterText(myTextSize)

            e.Graphics.DrawString(LightColorOffText, Me.Font, Brushes.Wheat, Textx, Texty)
        End If
    End Sub

    Private m_LightColorOnText As String = "ON"
    Public Property LightColorOnText As String
        Get
            Return m_LightColorOnText
        End Get
        Set(value As String)
            m_LightColorOnText = value
        End Set
    End Property

    Private m_LightColorOffText As String = "Off"
    Public Property LightColorOffText As String
        Get
            Return m_LightColorOffText
        End Get
        Set(value As String)
            m_LightColorOffText = value
        End Set
    End Property

    Private Sub CenterText(txtSize As SizeF)
        If Me.LegendPlate = LegendPlates.Large Then
            Texty = ((Me.Height * 0.68)) - (txtSize.Height / 2)
        Else
            Texty = (Me.Height * 0.59) - (txtSize.Height / 2)
        End If

        Textx = (Me.Width / 2) - (txtSize.Width / 2)
    End Sub

End Class


The height Centering code is a little hokey but effective.
I tried messing with the colors, but ran into a roadblock making the properties.
I haven't played with it yet, but would like a way for the font to be different.

I'm sure you know better ways to do this, but it does work.

Title: Re: Extending ADHMI Controls
Post by: rbelknap on October 20, 2015, 12:00:48 PM
ok, I have the different font working with this code.

First the Property
Code: [Select]
Private m_LightColorTextFont As System.Drawing.Font = Me.Font
    Public Property LightColorTextFont As System.Drawing.Font
        Get
            Return m_LightColorTextFont
        End Get
        Set(value As System.Drawing.Font)
            m_LightColorTextFont = value
        End Set
    End Property

and changes to the onPaint routine.
Code: [Select]

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        Dim myTextSize As New SizeF
        If Me.Value = True Then
            myTextSize = e.Graphics.MeasureString(LightColorOnText, LightColorTextFont)
            CenterText(myTextSize)

            e.Graphics.DrawString(LightColorOnText, LightColorTextFont, Brushes.Black, Textx, Texty)
        Else
            myTextSize = e.Graphics.MeasureString(LightColorOffText, LightColorTextFont)
            CenterText(myTextSize)

            e.Graphics.DrawString(LightColorOffText, LightColorTextFont, Brushes.Wheat, Textx, Texty)
        End If
    End Sub
Title: Re: Extending ADHMI Controls
Post by: Archie on October 20, 2015, 04:55:33 PM
If your objective is to place text on the Legend plate, you can leverage Mybase.Text and let the base class do all of the positioning.

For instance:
Code: [Select]
Protected Overrides Sub OnValueChanged(e As EventArgs)
    MyBase.OnValueChanged(e)

     If MyBase.Value = "True" Then
            MyBase.Text = LightColorOnText
            MyBase.Font = LightColorOnTextFont
        Else
            MyBase.Text = LightColorOffText
            MyBase.Font = LightColorOffTextFont
        End If
    End Sub
Title: Re: Extending ADHMI Controls
Post by: rbelknap on October 20, 2015, 05:47:28 PM
I was hoping to center the text on the lamp itself.

When I'm back inthe office tomorrow I will post a pic of what I have so far.
Title: Re: Extending ADHMI Controls
Post by: Archie on October 20, 2015, 06:04:39 PM
This is the trick I use for centering text:
Code: [Select]
Dim sf As New StringFormat
sf.Alignment = StringAlignment.Center
sf.LineAlignment = StringAlignment.Center
Dim TextRectangle As New Rectangle(0.Me.Height*0.2.Me.Width,Me.Height*0.8)
e.graphics.DrawString(MyBase.Text, MyBase.Font, TextBrush, TextRectangle, sf)

Title: Re: Extending ADHMI Controls
Post by: rbelknap on October 21, 2015, 07:41:51 AM
See the attached for what I have so far.

I like your solution better.
I'll integrate it and go from there.
Title: Re: Extending ADHMI Controls
Post by: Archie on October 21, 2015, 08:44:51 AM
Nice! Looks like you pretty much got it.
Title: Re: Extending ADHMI Controls
Post by: rbelknap on October 21, 2015, 08:47:33 AM
Your centering trick worked great.
The code is much cleaner now.

The only thing left on my wish list is to be able to change the color of the text with properties.

I would be ok with either a short list to choose from or the full color pallet.
Hopefully you have a trick for this too.

Thanks again for all of your help.
I know this thread will come in handy for any future mods I come up with.
Title: Re: Extending ADHMI Controls
Post by: rbelknap on October 21, 2015, 10:07:33 AM
Ok, I figured out the Text color properties.

It brings up the entire color pallet for choice.

You're doing some great work here Archie. 

Title: Re: Extending ADHMI Controls
Post by: joaco1993 on April 10, 2016, 07:21:10 PM
Hi ! I have downloaded the light.vb and opened. I can see the code but how to I do to see the graphics ??

thanks!
Title: Re: Extending ADHMI Controls
Post by: Archie on April 10, 2016, 07:54:09 PM
Hi ! I have downloaded the light.vb and opened. I can see the code but how to I do to see the graphics ??

thanks!
Did you right click the PurchasedControls folder in Solution Explorer and add the file to that?
Title: Re: Extending ADHMI Controls
Post by: joaco1993 on April 10, 2016, 08:42:17 PM
I mean i want to edit the graphics of the symbol.. like adding another shape to the object or change the colours..
Title: Re: Extending ADHMI Controls
Post by: Archie on April 10, 2016, 08:56:47 PM
I mean i want to edit the graphics of the symbol.. like adding another shape to the object or change the colours..
That will have to be done in the OnPaint subroutine. You will need to add code to it, such as this:
Code: [Select]
Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)

        e.Graphics.DrawEllipse(Pens.Red, 0, 0, Me.Width, Me.Height)
End Sub

This is advanced GDI+ programming and get complicated quickly.
Title: Re: Extending ADHMI Controls
Post by: joaco1993 on April 10, 2016, 09:12:48 PM
I see.. but for example I opened the squareiluminatedbutton.vb file which is in the controls folder, and inside this project couldnt find in the code something like you wrote before.. how is that squareiluminated button graphics done ??

I can see Plc related properties, events, contructor destriuctor, error display, etc

but nothing related to the object shape or grapchis
Title: Re: Extending ADHMI Controls
Post by: Archie on April 10, 2016, 09:31:23 PM
The code you are seeing is the AdvancedHMI extension to a Windows control. All of the controls start out as standard WinForms controls that have nothing to do with AdvancedHMI. They are inherited into a new class that gives them the functionality that enables them to work as AdvancedHMI controls.

If you notice the code snippet I gave above has a keyword "overrides". This means it will takeover the paint event that is in the underlying class. The MyBase.OnPaint(e) is telling it to continue to execute the underlying code, but add more code to it.
Title: Re: Extending ADHMI Controls
Post by: Godra on April 10, 2016, 10:14:11 PM
What Archie is saying is that you cannot change the graphics or the shape (because the base control is not accessible).
If you just need to have a square shaped pilot light then just use square illuminated button instead.

You can always paint over the PilotLight control (add text or new graphics, just like all the code in previous posts shows).

Here is a code example of adding a blue triangle to the base control, just after MyBase.OnPaint(e) (to look like the attached picture):

Code: [Select]
        Dim pointsTriangle As PointF()
        If Me.LegendPlate = LegendPlates.Large Then
            pointsTriangle = New PointF() {New PointF(Me.Width / 2, Me.Height / 2), _
                                                       New PointF(Me.Width / 4, Me.Height * 3 / 4), _
                                                       New PointF(Me.Width * 3 / 4, Me.Height * 3 / 4)}
        Else
            pointsTriangle = New PointF() {New PointF(Me.Width / 2, Me.Height / 3), _
                                                       New PointF(Me.Width / 4, Me.Height * 3 / 4), _
                                                       New PointF(Me.Width * 3 / 4, Me.Height * 3 / 4)}
        End If
        Dim gp As New GraphicsPath
        gp.AddPolygon(pointsTriangle)
        Using pgBrush As New PathGradientBrush(gp)
            pgBrush.CenterColor = Color.Blue
            pgBrush.SurroundColors = New Color() {Color.SteelBlue}
            e.Graphics.FillPolygon(pgBrush, pointsTriangle)
        End Using

To avoid errors you will also need to add the following statement at the top of the class: Imports System.Drawing.Drawing2D

I have also attached AHMI version of this PilotLightEx control (just slightly modified to allow show/hide of the text and also include the brightness settings somewhat similar to what was discussed in another topic).
Title: Re: Extending ADHMI Controls
Post by: joaco1993 on April 11, 2016, 03:53:57 PM
I see.. so its some how difficult to create new objects from the beginning..

I mean to create the grapchis for the pump for example, which is really well done I imagine you spent hours doing coding to get the shape you wanted..
Title: Re: Extending ADHMI Controls
Post by: Archie on April 11, 2016, 05:47:35 PM
I see.. so its some how difficult to create new objects from the beginning..

I mean to create the grapchis for the pump for example, which is really well done I imagine you spent hours doing coding to get the shape you wanted..
Creating photo realistic graphics, such as the water pump, using the GDI+ drawing commands alone would be extremely intensive if not impossible. The photo realistic controls in AdvancedHMI are done by drawing the graphics in either InkScape or Adobe Illustrator, then exporting it to a PNG file. These image files are then scaled and drawn using the e.graphics.DrawImage command.
Title: Re: Extending ADHMI Controls
Post by: joaco1993 on April 11, 2016, 08:38:35 PM
Sorry to keep bothering archie..

I opened the waterpump.vb file but cant find in any place where you import the png file..

Also another doubt.. at the beginnning of the code I see : '****************************************************************************
Public Class WaterPump
    Inherits MfgControl.AdvancedHMI.Controls.WaterPump

so it inherits the class itself ?? im confused you said these objects inherits the class of existing ones of .net studio..

Again, im a noob at this, but found intresting this scada and already comunicate with plc and store to sql and do some reports.. but now i want to go one more step

thanks!
Title: Re: Extending ADHMI Controls
Post by: Archie on April 11, 2016, 08:50:11 PM
The class MfgControl.AdvancedHMI.Controls.WaterPump is where it paints the png file. The WaterPump.vb that you are looking at is the AdvancedHMI layer. MfgControl.AdvancedHMI.Controls.WaterPump is the WinForms only class that has nothing to do with AdvancedHMI. AdvanceHMiControls.WaterPump is the class that implements the functionality that turns it into an AdvancedHMI capable control. The two classes have the same name, but are in different namespaces.

MfgControl.AdvancedHMI.Controls.WaterPump
AdvancedHMIControls.WaterPump

If you want to put in your own graphics, you will add this to the WaterPump.vb or you can make yet another class that inherits AdvancedHMIControls.WaterPump
Code: [Select]
Protected Overrides Sub OnPaint(e As PaintEventArgs)
       '* This performs the drawing of the default control
        MyBase.OnPaint(e)

        '* Perform your added drawing here
        g.DrawImage(YourGraphic, 0, 0)
End Sub
Title: Re: Extending ADHMI Controls
Post by: Archie on April 11, 2016, 08:53:12 PM
If you want to learn the complete process of building a control from scratch, see this thread:

http://advancedhmi.com/forum/index.php?topic=185.0
Title: Re: Extending ADHMI Controls
Post by: joaco1993 on April 11, 2016, 09:31:21 PM
thanks archie, i will have a look at that post, seems very helpfull !