Solved

How do I create shapes that I can click on (in vb.net)?

Posted on 2011-09-30
13
312 Views
Last Modified: 2012-05-12
I am creating a touchscreen app, but the same appies for a mouse-clic I suppose.

I think I know the answer to this, but I don't like it, so I'm hoping for a solution.
I'm a bit math challenged, so I'm not sure even how to start to tackle this problem.

Let's say I wanted to have a honecomb pattern of buttons that are interlocked.
I know you can just put a square button behind a shape like a banana etc, but what if I want a honecomb shaped button exactly? It sounds like some complex math problem.
The only way I can think of doing this would be to create an table of X and Y positions I suppose of where each shape begins and ends horizontally and vertically like this:

Y axis table:

Pixel  Start     Pixel End       Zone Name
    5                    100                Beep


Then I would send the mouse coordinates to look up the X and Y axis of the click to find
the zone name.

Is this the best I can do, or does .NET 4.0 have some other way of doing this that is much easier?
0
Comment
Question by:harmono
  • 8
  • 5
13 Comments
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 36894831
There are other ways of doing it...

You can modify a button (or panel) so that it is actually a honeycomb shape using its Region() property.  First create a GraphicsPath with the honeycomb shape and then pass that to a new Region.
0
 
LVL 1

Author Comment

by:harmono
ID: 36894846
Idle Mind,

Thanks.
I looked up region and graphicspath and found this article. Nice! It's C# but good enough, I might do this in C#, I'm just doing research and development and prototyping for now.

http://www.java2s.com/Code/CSharp/2D-Graphics/CreateaRegionwhoseboundaryistheGraphicsPath.htm
0
 
LVL 1

Author Comment

by:harmono
ID: 36894858
PS - The shapes don't have to be as complex as a honeycomb, but they are more complex than a rectangle or square, more like a parallelogram. For example, a picture of a banana with a parallelogram type shape (herringbone?) for each banana in a bunch. If you click on a banana, the shape is clicked, the user doesn't have to know they are clicking a herringbone shape, it just has to be able to fit like a bunch of bananas.
0
How our DevOps Teams Maximize Uptime

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us. Read the use case whitepaper.

 
LVL 1

Author Comment

by:harmono
ID: 36894872
This article helps too, but I don't see much of an explanation of how the code works:

http://www.java2s.com/Tutorial/VB/0260__GUI/IrregularshapeofButton.htm
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 125 total points
ID: 36894880
Here's something I was playing around with awhile ago... Idle-Mind-508447.flv
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim letters(,) As String = {{"I", "D", "L", "E"}, {"M", "I", "N", "D"}, {"W", "A", "S", ""}, {"H", "E", "R", "E"}}
        Dim lx, ly As Integer
        For y As Integer = 0 To letters.GetUpperBound(1)
            lx = 0
            ly = y * 100
            For x As Integer = 0 To letters.GetUpperBound(0)
                Dim hb As New Hexagon
                hb.Text = letters(x, y)
                hb.Location = New Point(lx, IIf(x Mod 2 = 0, ly, ly + 50))
                lx = lx + (hb.Width * (1 - hb.P))
                AddHandler hb.Click, AddressOf hb_Click
                Me.Controls.Add(hb)
            Next
        Next

        Dim hx2 As New Hexagon2
        hx2.Text = "Hexagon"
        hx2.BackColor = Color.Red
        hx2.Location = New Point(400, 25)
        Me.Controls.Add(hx2)
    End Sub

    Private Sub hb_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim hb As Hexagon = DirectCast(sender, Hexagon)
        hb.Enabled = False
    End Sub

    Public Class Hexagon2
        Inherits Button

        Public Sub New()
            Me.FlatStyle = Windows.Forms.FlatStyle.Flat
            Me.FlatAppearance.BorderSize = 0
            Me.Size = New Size(100, 100)
            Me.Font = New Font("Microsoft Sans Serif", 14)
            Me.TextAlign = ContentAlignment.MiddleCenter            

            Dim P As Single = 0.25
            Dim gp As New System.Drawing.Drawing2D.GraphicsPath
            Dim pts() As Point = {New Point(0, Me.Height / 2), New Point(Me.Width * P, 0), New Point(Me.Width * (1.0 - P)), New Point(Me.Width, Me.Height / 2), New Point(Me.Width * (1.0 - P), Me.Height), New Point(Me.Width * P, Me.Height)}
            gp.AddPolygon(pts)
            Me.Region = New Region(gp)
        End Sub

    End Class

    Public Class Hexagon
        Inherits Button

        Private _P As Single = 0.25
        Private gpA As New System.Drawing.Drawing2D.GraphicsPath
        Private gpB As New System.Drawing.Drawing2D.GraphicsPath

        Public ReadOnly Property P() As Single
            Get
                Return _P
            End Get
        End Property

        Public Sub New()
            Me.FlatStyle = Windows.Forms.FlatStyle.Flat
            Me.FlatAppearance.BorderSize = 0
            Me.Size = New Size(100, 100)
            Me.Font = New Font("Microsoft Sans Serif", 14)

            Dim gp As New System.Drawing.Drawing2D.GraphicsPath

            Dim pts() As Point = {New Point(0, Me.Height / 2), New Point(Me.Width * P, 0), New Point(Me.Width * (1.0 - P)), New Point(Me.Width, Me.Height / 2), New Point(Me.Width * (1.0 - P), Me.Height), New Point(Me.Width * P, Me.Height)}
            gp.AddPolygon(pts)
            Me.Region = New Region(gp)

            Dim ptA As Point
            Dim rf As RectangleF
            Dim M As New System.Drawing.Drawing2D.Matrix

            gpA = gp.Clone
            M.Scale(0.98, 0.98)
            gpA.Transform(M)
            rf = gpA.GetBounds
            ptA = New Point(Me.Width / 2 - rf.Width / 2, Me.Height / 2 - rf.Height / 2)
            M.Reset()
            M.Translate(ptA.X - rf.Left, ptA.Y - rf.Top)
            gpA.Transform(M)

            gpB = gp.Clone
            M.Scale(0.8, 0.8)
            gpB.Transform(M)
            rf = gpB.GetBounds
            ptA = New Point(Me.Width / 2 - rf.Width / 2, Me.Height / 2 - rf.Height / 2)
            M.Reset()
            M.Translate(ptA.X - rf.Left, ptA.Y - rf.Top)
            gpB.Transform(M)

            Me.BackColor = Color.Goldenrod
        End Sub

        Private Sub Hexagon_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            e.Graphics.DrawPath(Pens.Black, gpA)
            e.Graphics.FillPath(IIf(Me.Enabled, Brushes.Yellow, Brushes.Red), gpB)
            e.Graphics.DrawPath(Pens.Black, gpB)
            Dim sz As SizeF = e.Graphics.MeasureString(Me.Text, Me.Font, Me.Width)
            e.Graphics.DrawString(Me.Text, Me.Font, Brushes.Black, Me.Width / 2 - sz.Width / 2, Me.Height / 2 - sz.Height / 2)
        End Sub

    End Class

End Class

Open in new window

0
 
LVL 1

Author Closing Comment

by:harmono
ID: 36894888
Wow! A solution that matched my question perfectly. I mentioned a honeycomb shaped grid of buttons, and voila!
0
 
LVL 1

Author Comment

by:harmono
ID: 36894892
The "W" needs to have the code added, it didn't respond to the MouseHover by the way. Very cool!
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 36894904
Really?...I'll have to take a closer look at the code.  I haven't played with it since August 2009!
0
 
LVL 1

Author Comment

by:harmono
ID: 36894909
I tried it and the W works, so maybe you fixed it. When was this recorded?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 36894915
I just upgraded my old code to VS2010 and then used the EE screencast tool to record it in action.  The recorder probably wasn't fast enough to see the change?
0
 
LVL 1

Author Comment

by:harmono
ID: 36894923
That's strange since you hover over the W twice, and you were moving over just as fast as other buttons, and you even went over the W and turned as though you were trying to get it to work.
0
 
LVL 1

Author Comment

by:harmono
ID: 36894927
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 36894928
Lemme know if you have any questions about the code.  I'll do my best to decipher my old scratch...  =)
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction This article explores the design of a cache system that can improve the performance of a web site or web application.  The assumption is that the web site has many more “read” operations than “write” operations (this is commonly the ca…
Introduction This question got me thinking... (http://www.experts-exchange.com/questions/28707487/GLOBALS.html) Why shouldn't we use Globals? This is a simple question without a simple answer.  How do you explain these concepts to a programmer w…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question