Click here to Skip to main content
15,885,025 members
Articles / Desktop Programming / Windows Forms

Shape Control for .NET

Rate me:
Please Sign up or sign in to vote.
4.84/5 (170 votes)
23 Mar 2017CPOL10 min read 379.3K   21.6K   301  
Implementing shape control that supports transparency, custom design-time editors and simple animation
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Linq;
using System.IO;

namespace TestShapeControl
{
    public partial class Form3 : Form
    {
        List<ShapeControl.CustomControl1> ctrllist = new List<ShapeControl.CustomControl1>();
        private int sx, sy;

        private int static_i = 0;
        private bool ctrlKey = false;
        private bool altKey = false;
        private bool plusKey = false;
        private bool minusKey = false;
        public Form3()
        {
            InitializeComponent();
        }

        private void btnAddCam_Click(object sender, EventArgs e)
        {
            AddCam("");
        }

        private int getNextCamIndex()
        {
            if (ctrllist.Count == 0) return 1;

            var tempvar = ctrllist.OrderBy(x => x.Name);
            tempvar=tempvar.OrderBy(x => x.Name.Length);
            List<ShapeControl.CustomControl1> templist =tempvar.ToList();
            int count = templist.Count;
            int retval = count+1;
            
            //find missing index
            for (int i = 0; i < count; i++)
            {
                string ctrlname = templist[i].Name;
                string ctrlindex = ctrlname.Substring(3);
                if ((i + 1) != int.Parse(ctrlindex))
                {
                    retval = (i + 1);
                    break;
                }
            }


            return retval;
        }



        private void AddCam(string caminfo)
        {

            
            bool bNew =(caminfo =="");
            string name="";
            string tag = "",tag2 = "";
            int x = 0, y = 0, w = 0, h = 0, c = 0;

            if (caminfo != "")
            {
                var info = caminfo.Split('|');
                for (int i = 0; i < info.Length; i++)
                {
                    var details = info[i].Split('=');
                    switch (details[0])
                    {
                        case "name": name = details[1]; break;
                        case "x": x = int.Parse (details[1]); break;
                        case "y": y = int.Parse (details[1]); break;
                        case "w": w = int.Parse(details[1]); break;
                        case "h": h = int.Parse(details[1]); break;
                        case "c": c = int.Parse(details[1]); break;
                        case "tag": tag = details[1]; break;
                        case "tag2": tag2 = details[1]; break; 
                    }

                }
            }
            ShapeControl.CustomControl1 ctrl1 = new ShapeControl.CustomControl1();
            
           // ctrllist.Add(ctrl1);
            ctrl1.BackColor = bNew?System.Drawing.Color.FromArgb(((int)(((byte)(126)))),Color.Red):Color.FromArgb(c);
            ctrl1.Blink = false;
            ctrl1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
            ctrl1.BorderStyle = System.Drawing.Drawing2D.DashStyle.Solid;
            ctrl1.BorderWidth = 3;
          //  ctrl1.CenterColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(255)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
            ctrl1.Font = new System.Drawing.Font("Arial", 8f, System.Drawing.FontStyle.Bold);
                
            ctrl1.Name =bNew? "cam" + getNextCamIndex():name ;//ctrllist.Count;
            ctrl1.Shape = ShapeControl.ShapeType.Ellipse;
            ctrl1.ShapeImage = ((System.Drawing.Image)global::TestShapeControl.Properties.Resources.camshape);
            ctrl1.Size = bNew? new System.Drawing.Size(40, 40):new System.Drawing.Size(w,h);
           // ctrl1.SurroundColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
            ctrl1.TabIndex = 0;
            ctrl1.UseGradient = false;
            ctrl1.Vibrate = false;
            ctrl1.Visible = true;
            
            ctrl1.MouseDown += new MouseEventHandler(ctrl1_MouseDown);
            ctrl1.MouseMove += new MouseEventHandler(ctrl1_MouseMove);
            ctrl1.MouseUp += new MouseEventHandler(ctrl1_MouseUp);
            ctrl1.MouseDoubleClick += new MouseEventHandler(ctrl1_MouseDoubleClick);
            ctrl1.MouseHover += new EventHandler(ctrl1_MouseHover);
            ctrllist.Add(ctrl1);
            int ypos = (50 * ctrllist.Count) % panel1.Height ;
            int xpos = ((50 * ctrllist.Count) / panel1.Height) * 50;
            
            ctrl1.Location =bNew? new System.Drawing.Point(50 + xpos, ypos-20):new System.Drawing.Point(50,50);
            this.panel1.Controls.Add(ctrl1);
            ctrl1.Text = "cam";
            ctrl1.Text = bNew ?(string)ctrl1.Name.ToString().Clone(): name ;
            ctrl1.BringToFront();
            ctrl1.Tag2=bNew? "127.0.0.1:New cam":tag2;
            //set the color
            if(bNew)
              ctrl1_MouseDoubleClick(ctrl1, new MouseEventArgs(MouseButtons.Left,2,0,0,0));


            float dy = (float)(ctrl1.Top + ctrl1.Height /2) - (float)panel1.Height/2;
            float dx = (float)(ctrl1.Left +ctrl1.Width /2) -(float) panel1.Width/2;

            ctrl1.Tag = bNew? (dx + "," + dy+ "," +getNumPixelforImageDisplayed()):tag;
            
        }

        void ctrl1_MouseUp(object sender, MouseEventArgs e)
        {
            //if (e.Button.Equals(MouseButtons.Left))
            //   ((ShapeControl.CustomControl1)sender).Region = tempregion;
        }

        void ctrl1_MouseHover(object sender, EventArgs e)
        {
            toolTip1.Show(((ShapeControl.CustomControl1)sender).Tag2 + ",(" +
                ((ShapeControl.CustomControl1)sender).Left + "," + ((ShapeControl.CustomControl1)sender).Top +")", 
                (ShapeControl.CustomControl1)sender, 2000);
        }

        private void ctrl1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Clicks < 2) return;

            if(e.Button.Equals(MouseButtons.Left))
            {
                if (plusKey && !minusKey)
                {
                    if (((ShapeControl.CustomControl1)sender).Width < 80)
                    {
                      ((ShapeControl.CustomControl1)sender).Size=
                          new Size(((ShapeControl.CustomControl1)sender).Width +5,((ShapeControl.CustomControl1)sender).Height+5);
 
                    }
                    plusKey = false;
                    return;
                }

                if (minusKey && !plusKey)
                {
                    if (((ShapeControl.CustomControl1)sender).Width > 20)
                    {
                        ((ShapeControl.CustomControl1)sender).Size =
                            new Size(((ShapeControl.CustomControl1)sender).Width - 5, ((ShapeControl.CustomControl1)sender).Height - 5);

                    }
                    minusKey = false;
                    return;
                }
                if(ctrlKey && !altKey)
                {
                   DialogResult dr=MessageBox.Show (this,"Delete cam?","Delete",MessageBoxButtons.OKCancel);
                    if (dr==DialogResult.OK )
                    {
                        ctrllist.Remove((ShapeControl.CustomControl1)sender);
                        panel1.Controls.Remove((ShapeControl.CustomControl1)sender);
                    }
                    ctrlKey = false;
                    return;
      
                }

                if (altKey && !ctrlKey )
                {
                    ((ShapeControl.CustomControl1)sender).Vibrate = !((ShapeControl.CustomControl1)sender).Vibrate;
                    altKey = false;
                    return;
                }
         
                if (static_i >= 6) static_i = 0;
                switch (static_i)
                {
                    case 0:
                       ((ShapeControl.CustomControl1)sender).BackColor = System.Drawing.Color.FromArgb(126, Color.Red);
                       break; 
                    case 1:
                       ((ShapeControl.CustomControl1)sender).BackColor = System.Drawing.Color.FromArgb(126, Color.Blue);
                       
                        break;

                    case 2:
                        ((ShapeControl.CustomControl1)sender).BackColor = System.Drawing.Color.FromArgb(126, Color.Green);
                      
                        break;

                    case 3:
                        ((ShapeControl.CustomControl1)sender).BackColor = System.Drawing.Color.FromArgb(126, Color.Wheat );
                        break;
                    case 4:
                        ((ShapeControl.CustomControl1)sender).BackColor = System.Drawing.Color.FromArgb(126, Color.GreenYellow);

                        break;

                    case 5:
                        ((ShapeControl.CustomControl1)sender).BackColor = System.Drawing.Color.FromArgb(126, Color.Cyan);

                        break;

               }
                 static_i++;
            }

            
        }

        private void ctrl1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button.Equals(MouseButtons.Left))
            {
                sx = e.X;
                sy = e.Y;
                //tempregion = ((ShapeControl.CustomControl1)sender).Region.Clone();
                //((ShapeControl.CustomControl1)sender).Region = null;
            }

            if(e.Button.Equals(MouseButtons.Right))
            {
                FormProperty frm = new FormProperty();
                frm.Caller  = (ShapeControl.CustomControl1)sender;
                
                frm.ShowDialog();


            }
        }

        private void ctrl1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
           
            if (e.Button.Equals(MouseButtons.Left))
            {
                ((Control)sender).Left = ((Control)sender).Left + (e.X - sx);
                ((Control)sender).Top = ((Control)sender).Top + (e.Y - sy);



                float dy = (float)((Control)sender).Top + ((Control)sender).Height / 2 - (float)panel1.Height / 2;
                float dx = (float)((Control)sender).Left + ((Control)sender).Width / 2 - (float)panel1.Width / 2;
                ((Control)sender).Tag = dx + "," + dy + "," + getNumPixelforImageDisplayed();
            }
        }

        private void Form3_KeyDown(object sender, KeyEventArgs e)
        {
            ctrlKey = e.Control;
            altKey = e.Alt;
            if (e.KeyCode == Keys.OemMinus) minusKey = true;
            if (e.KeyCode == Keys.Oemplus ) plusKey = true;
        }

        private void Form3_KeyUp(object sender, KeyEventArgs e)
        {
            ctrlKey =false  ;
            altKey = false;
            minusKey = false;
            plusKey = false;
        }

        private void panel1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            openFileDialog1.Filter="Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*";
            DialogResult dr=openFileDialog1.ShowDialog();
            if (dr == DialogResult.OK)
            {
                try
                {
                    using (var tempImage = new Bitmap(openFileDialog1.FileName))
                    {
                        panel1.BackgroundImage = new Bitmap(tempImage);
                    }
                }
                catch
                {

                }
            }

        }

        private int getNumPixelforImageDisplayed()
        {
            float panelratio = (float)panel1.Width / panel1.Height;
            float imgratio = (float)panel1.BackgroundImage.Width / (float)panel1.BackgroundImage.Height;
            float dispwidth,dispheight;
            if (panelratio > imgratio) //height limiting
            {
                dispheight = panel1.Height;
                dispwidth = imgratio * dispheight;
            }
            else
            {
                dispwidth = panel1.Width;
                dispheight = dispwidth / imgratio;
            }

           // System.Diagnostics.Debug.Print(imgratio +"," + dispwidth + "," + dispheight);
            
            return (int) (dispwidth * dispheight);
        }


        private void button2_Click(object sender, EventArgs e)
        {
            label1.Text ="NewMap_" + Guid.NewGuid().ToString() +".map";
            panel1.BackgroundImage = new Bitmap(panel1.Width, panel1.Height);
            Graphics.FromImage(panel1.BackgroundImage).FillRectangle(Brushes.White, new Rectangle(0, 0, panel1.Width, panel1.Height));
            Graphics.FromImage(panel1.BackgroundImage).DrawString("Dbl Click here to insert floor plan..",
                                 new Font(FontFamily.GenericSansSerif, 12), Brushes.Black, 50, 50);
            ctrllist.Clear();
            panel1.Controls.Clear();

        }

        private void button1_Click(object sender, EventArgs e)
        {
            using (StreamWriter writer = File.CreateText(label1.Text))
            {
                var tempvar=ctrllist.OrderBy(x=>x.Name);
                tempvar  =tempvar.OrderBy(x=>x.Name.Length);
                List<ShapeControl.CustomControl1 > templist=tempvar.ToList();
                writer.WriteLine("CAM_COUNT=" + templist.Count);
                for (int i = 0; i < ctrllist.Count; i++)
                {
                    writer.WriteLine("name=" + templist[i].Name + "|" +
                                     "x=" + templist[i].Left + "|" +
                                     "y=" + templist[i].Top + "|" +
                                     "w=" + templist[i].Width + "|" +
                                     "h=" + templist[i].Height + "|" +
                                     "c=" + templist[i].BackColor.ToArgb()+ "|" +
                                     "tag=" + templist[i].Tag.ToString()+"|"+
                                     "tag2="+templist[i].Tag2.ToString());
                    
                }
            }
            if (panel1.BackgroundImage != null)
                panel1.BackgroundImage.Save(label1.Text + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

            MessageBox.Show(label1.Text + " is saved");
        }

        private void Form3_Load(object sender, EventArgs e)
        {

            this.DoubleBuffered = true;

            //invoke double buffer 
            typeof(Panel ).InvokeMember(
               "DoubleBuffered",
               System.Reflection.BindingFlags.NonPublic | 
               System.Reflection.BindingFlags.Instance | 
               System.Reflection.BindingFlags.SetProperty,
               null,
               panel1,
               new object[] { true });

            label2.Text = "On Cam> Right Click:Set Properties, Dbl_Click:Change Color, Ctl+Dbl_Click:Del, Alt+Dbl_Click:Vibrate, Minus+Dbl_Click:Smaller, Plus+Dbl_Click:Larger";
            button2_Click(null, null);
        }

        private void btnImportMap_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "Map files (*.map)|*.map";
            DialogResult dr = openFileDialog1.ShowDialog();
            if (dr == DialogResult.OK)
            {

                button2_Click(null, null);
                label1.Text = openFileDialog1.FileName;

                try
                {
                    using (StreamReader reader = File.OpenText(label1.Text))
                    {
                        string s = reader.ReadLine();
                        var info = s.Split('=');
                        for (int i = 0; i < int.Parse(info[1]); i++)
                        {
                            s = reader.ReadLine();
                            AddCam(s);
                        }


                       
                    }

                //    this.panel1.Visible = false;
                    if(File.Exists(openFileDialog1.FileName+".jpg"))
                    using (var tempImage = new Bitmap(openFileDialog1.FileName+".jpg"))
                    {
                        panel1.BackgroundImage = new Bitmap(tempImage);
                    }


                    //resize

                    updateCamPosAfterResize();
                 //   this.panel1.Visible = true;
                }
                catch
                {

                }
            }

        }


        private void updateCamPosAfterResize()
        {
            int newarea = getNumPixelforImageDisplayed();
     

            for (int i = 0; i < ctrllist.Count; i++)
            {
                var info = ctrllist[i].Tag.ToString().Split(',');
                float dx = float.Parse(info[0]);
                float dy = float.Parse(info[1]);
                int area = int.Parse(info[2]);
                float ratio = (float)Math.Sqrt((float)newarea / area);
                float newdx=ratio * dx;
                float newdy=ratio * dy;
              //  ctrllist[i].Tag = dx + "," + dy + "," + newarea;

                ctrllist[i].Left = (int)(panel1.Width / 2 + newdx - ctrllist[i].Width / 2);
                ctrllist[i].Top = (int)(panel1.Height / 2 + newdy - ctrllist[i].Height / 2);

            }



        }

        private void Form3_Resize(object sender, EventArgs e)
        {
  
            this.panel1.Visible = false;

            panel1.Height = this.ClientSize.Height - ( 3* panel1.Top/2);
            panel1.Width = this.ClientSize.Width - 2 * panel1.Left;
            label2.Top = panel1.Top + panel1.Height + 10;
            updateCamPosAfterResize();

            this.panel1.Visible = true;

        }



    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Singapore Singapore
Coder. Hacker. Fixer.

Comments and Discussions