BaoKai_202508-Wms-Jingwang..../ShapeControl_CodeProject/ShapeControl.cs
2025-08-24 09:35:55 +08:00

1564 lines
56 KiB
C#

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.IO;
namespace ShapeControl
{
public enum LineDirection
{
None,
RightUp,
RightDown,
LeftUp,
LeftDown
}
public enum ConnecterType
{
Top,
Right,
Bottom,
Left,
Center
}
//All the defined shape type
public enum ShapeType{ Rectangle,
RoundedRectangle,
Diamond,
Ellipse,
TriangleUp,
TriangleDown,
TriangleLeft,
TriangleRight,
BallonNE,
BallonNW,
BallonSW,
BallonSE,
CustomPolygon,
CustomPie,
LineDown,
LineUp,
LineHorizontal,
LineVertical
}
public class CustomControl1 : System.Windows.Forms.Control
{
private string _shapestorageloadfile = "";
private string _shapestoragesavefile = "";
private GraphicsPath _custompath = new GraphicsPath();
private IContainer components;
ConnecterType _connector = ConnecterType.Center;
LineDirection _direction = LineDirection.None;
ShapeType _shape=ShapeType.Rectangle;
DashStyle _borderstyle=DashStyle.Solid;
Color _bordercolor=Color.FromArgb(255,255,0,0);
int _borderwidth=3;
GraphicsPath _outline=new GraphicsPath();
bool _usegradient=false;
bool _blink = false;
bool _vibrate = false;
bool _voffseted = false;
bool _animateborder = false;
int _prevborderwidth = 3;
Color _prevbordercolor = Color.Red;
bool _btoggled = false;
int _static_ds = 0;
DashStyle _prevborderstyle = DashStyle.Solid;
Color _centercolor=Color.FromArgb(100,255,0,0) ;
Color _surroundcolor=Color.FromArgb(100,0,255,255);
private Timer timer1;
private Timer timer2;
string _tag2 = "";
private Timer timer3;
Bitmap _bm; //for shapeimage property
Bitmap _bmtexture; //for shapeimagetexture property
private int _shapeimagerotation=0;
public GraphicsPath Outline
{
get { return _outline; }
}
[Category("Shape"), Description("Shape Storage Load File")]
[EditorAttribute(typeof(FileLoadEditor), typeof(System.Drawing.Design.UITypeEditor))]
public string ShapeStorageLoadFile
{
set {
LoadFromFile(this, value, true);
}
get {
return _shapestorageloadfile;
}
}
[Category("Shape"), Description("Shape Storage Save File")]
[EditorAttribute(typeof(FileSaveEditor), typeof(System.Drawing.Design.UITypeEditor))]
public string ShapeStorageSaveFile
{
set
{
if(value.Length<8) return;
if (value.ToUpper().IndexOf(".SHP.JPG") != value.Length - 8)
{
SaveToFile(this, value + ".shp.jpg", true);
}
else
SaveToFile(this, value, true);
}
get
{
return _shapestoragesavefile;
}
}
[Category("Shape"), Description("Connect at")]
public ConnecterType Connector
{
get { return _connector; }
set {_connector =value; }
}
[Category("Shape"), Description("For Directional Line")]
public LineDirection Direction
{
get { return _direction; }
set {
_direction = value;
OnResize(null);
}
}
[Category("Shape"), Description("Additional user-defined data")]
public string Tag2
{
get { return _tag2; }
set
{
_tag2 = value;
}
}
[Category("Shape"), Description("Causes the control border to animate")]
public bool AnimateBorder
{
get { return _animateborder; }
set
{
_animateborder = value;
if (_animateborder)
{
//save all the border
_prevborderstyle = _borderstyle;
_prevborderwidth = _borderwidth;
_prevbordercolor = _bordercolor;
if (_borderwidth == 0)
_borderwidth = 3;
int a, r, g, b;
a = _bordercolor.A;
r = _bordercolor.R;
g = _bordercolor.G;
b = _bordercolor.B;
_bordercolor = Color.FromArgb(255, r, g, b);
}
else
{
_borderwidth=_prevborderwidth ;
_bordercolor=_prevbordercolor ;
this.BorderStyle =_prevborderstyle;
}
timer3.Enabled = _animateborder;
}
}
[Category("Shape"), Description("Causes the control to blink")]
public bool Blink
{
get { return _blink; }
set {
_blink = value;
timer1.Enabled = _blink;
if (!_blink) this.Visible = true;
}
}
[Category("Shape"), Description("Causes the control to vibrate")]
public bool Vibrate
{
get { return _vibrate; }
set
{
_vibrate = value;
timer2.Enabled = _vibrate;
if (!_vibrate)
if (_voffseted) { this.Top += 5; _voffseted = false; }
}
}
[Category("Shape"), Description("Rotation angle in deg for ShapeImage\nValid values between -180 and 180")]
public int ShapeImageRotation
{
get
{
return _shapeimagerotation;
}
set
{
if (value >= -180 && value <= 180)
{
_shapeimagerotation = value;
if (_bm != null)
{
OnResize(null);
}
}
}
}
[Category("Shape"), Description("Background Image to define outline")]
public Image ShapeImage
{
get
{
return _bm;
}
set
{
if (value != null)
{
_bm = (Bitmap)value.Clone();
Width = 150;
Height = 150;
OnResize(null);
}
else
{
if(_bm!=null)
_bm = null;
OnResize(null);
}
}
}
[Category("Shape"), Description("Texture Image for ShapeImage")]
public Image ShapeImageTexture
{
get
{
return _bmtexture;
}
set
{
if (value != null)
{
_bmtexture = (Bitmap)value.Clone();
OnResize(null);
}
else
{
if (_bmtexture != null)
_bmtexture = null;
OnResize(null);
}
}
}
[Category("Shape"),Description("Text to display")]
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
}
}
//Overide the BackColor Property to be associated with our custom editor
[Category("Shape"),Description("Back Color")]
[BrowsableAttribute(true)]
[EditorAttribute(typeof(ColorEditor), typeof(System.Drawing.Design.UITypeEditor))]
public override Color BackColor
{
get
{
return base.BackColor;
}
set
{
base.BackColor = value; this.Refresh();
}
}
[Category("Shape"),Description("Using Gradient to fill Shape")]
public bool UseGradient
{
get{ return _usegradient;}
set{ _usegradient=value; this.Refresh();}
}
//For Gradient Rendering, this is the color at the center of the shape
[Category("Shape"),Description("Color at center")]
[BrowsableAttribute(true)]
[EditorAttribute(typeof(ColorEditor), typeof(System.Drawing.Design.UITypeEditor))]
public Color CenterColor
{
get {return _centercolor;}
set { _centercolor=value; this.Refresh();}
}
//For Gradient Rendering, this is the color at the edges of the shape
[Category("Shape"),Description("Color at the edges of the Shape")]
[BrowsableAttribute(true)]
[EditorAttribute(typeof(ColorEditor), typeof(System.Drawing.Design.UITypeEditor))]
public Color SurroundColor
{
get {return _surroundcolor;}
set { _surroundcolor=value; this.Refresh();}
}
[Category("Shape"),Description("Border Width")]
public int BorderWidth
{
get{
return _borderwidth;
}
set{
_borderwidth=value;
if (_borderwidth<0) _borderwidth=0;
OnResize(null);
}
}
[Category("Shape"),Description("Border Color")]
[BrowsableAttribute(true)]
[EditorAttribute(typeof(ColorEditor), typeof(System.Drawing.Design.UITypeEditor))]
public Color BorderColor
{
get{return _bordercolor;}
set{_bordercolor=value;this.Refresh();}
}
[Category("Shape"),Description("Border Style")]
public DashStyle BorderStyle
{
get{return _borderstyle;}
set{_borderstyle=value;this.Refresh();}
}
[Category("Shape"),Description("Select Shape")]
[BrowsableAttribute(true)]
[EditorAttribute(typeof(ShapeTypeEditor), typeof(System.Drawing.Design.UITypeEditor))]
public ShapeType Shape
{
get{return _shape;}
set
{
_shape=value;
if (_shape == ShapeType.LineVertical ||
_shape == ShapeType.LineHorizontal ||
_shape == ShapeType.LineUp ||
_shape == ShapeType.LineDown)
ForeColor = Color.FromArgb(0, 255, 255, 255);
if (_shape == ShapeType.LineVertical)
this.Width = 20;
if (_shape == ShapeType.LineHorizontal)
this.Height = 20;
OnResize(null);
}
}
public CustomControl1()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
this.DoubleBuffered = true;
//Using of Double Buffer allow for smooth rendering
//minizing flickering
this.SetStyle(ControlStyles.SupportsTransparentBackColor |
ControlStyles.DoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint,true);
//set the default backcolor and font
this.BackColor=Color.FromArgb(0,255,255,255);
this.Font =new Font("Arial",12,FontStyle.Bold);
this.Width = 100;
this.Height = 100;
this.Text = "";
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}
#region Component Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.timer2 = new System.Windows.Forms.Timer(this.components);
this.timer3 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// timer1
//
this.timer1.Interval = 200;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// timer2
//
this.timer2.Interval = 200;
this.timer2.Tick += new System.EventHandler(this.timer2_Tick);
//
// timer3
//
this.timer3.Tick += new System.EventHandler(this.timer3_Tick);
//
// CustomControl1
//
this.TextChanged += new System.EventHandler(this.ShapeControl_TextChanged);
this.ResumeLayout(false);
}
#endregion
//This function creates the path for each shape
//It is also being used by the ShapeTypeEditor to create the various shapes
//for the Shape property editor UI
internal static void updateOutline(ref GraphicsPath outline,ShapeType shape,int width,int height,int borderwidth)
{
switch(shape)
{
case ShapeType.LineVertical :
outline.AddLine(new PointF((float)width / 2, borderwidth),
new PointF((float)width / 2, height - borderwidth));
break;
case ShapeType.LineHorizontal:
outline.AddLine(new PointF(borderwidth, (float)height / 2 ) , new PointF(width - borderwidth, (float)height / 2 ));
break;
/////////////////////////////
// *
// *
// *
// *
//*
//////////////////////////////
case ShapeType.LineUp:
outline.AddLine(new PointF(borderwidth, height - borderwidth), new PointF(width - borderwidth, borderwidth));
break;
////////////////////////////
// *
// *
// *
// *
// *
/////////////////////////////
case ShapeType.LineDown :
outline.AddLine(new PointF(borderwidth , borderwidth ), new PointF(width - borderwidth , height - borderwidth));
break;
case ShapeType.CustomPie:
outline.AddPie(0,0,width,height,180,270);
break;
case ShapeType.CustomPolygon:
outline.AddPolygon(new PointF[]{
new PointF(0,0),
new PointF((float)width/2,(float)height/4),
new PointF((float)width,0),
new PointF(((float)width*3)/4,(float)height/2),
new PointF((float)width,(float)height),
new PointF((float)width/2,((float)height*3)/4),
new PointF(0,(float)height),
new PointF((float)width/4,(float)height/2)
}
);
break;
case ShapeType.Diamond :
outline.AddPolygon(new PointF[]{
new PointF(0,(float)height/2),
new PointF((float)width/2,0),
new PointF((float)width,(float)height/2),
new PointF((float)width/2,(float)height)
});
break;
case ShapeType.Rectangle :
outline.AddRectangle(new RectangleF(0,0,width,height));
break;
case ShapeType.Ellipse:
outline.AddEllipse(0,0,(float)width,(float)height);
break;
case ShapeType.TriangleUp:
outline.AddPolygon(new PointF[]{new PointF(0,(float)height),new PointF((float)width,(float)height),new PointF((float)width/2,0)});
break;
case ShapeType.TriangleDown:
outline.AddPolygon(new PointF[]{new PointF(0,0),new PointF(width,0),new PointF(width/2,(float)(float)height)});
break;
case ShapeType.TriangleLeft:
outline.AddPolygon(new PointF[]{new PointF(width,0),new PointF(0,(float)(float)height/2),new PointF(width,(float)(float)height)});
break;
case ShapeType.TriangleRight:
outline.AddPolygon(new PointF[]{new PointF(0,0),new PointF(width,(float)(float)height/2),new PointF(0,(float)(float)height)});
break;
case ShapeType.RoundedRectangle:
outline.AddArc(0,0,(float)width/4,(float)width/4,180,90);
outline.AddLine((float)width/8,0,(float)width-(float)width/8,0);
outline.AddArc((float)width-(float)width/4,0,(float)width/4,(float)width/4,270,90);
outline.AddLine((float)width,(float)width/8,(float)width,(float)height-(float)width /8);
outline.AddArc((float)width-(float)width/4,(float)height-(float)width/4,(float)width/4,(float)width/4,0,90);
outline.AddLine((float)width-(float)width/8,(float)height,(float)width/8,(float)height);
outline.AddArc(0,(float)height-(float)width/4,(float)width/4,(float)width/4,90,90);
outline.AddLine(0,(float)height-(float)width/8,0,(float)width/8);
break;
case ShapeType.BallonSW:
outline.AddArc(0,0,(float)width/4,(float)width/4,180,90);
outline.AddLine((float)width/8,0,(float)width-(float)width/8,0);
outline.AddArc((float)width-(float)width/4,0,(float)width/4,(float)width/4,270,90);
outline.AddLine((float)width,(float)width/8,(float)width,((float)height*0.75f)-(float)width /8);
outline.AddArc((float)width-(float)width/4,((float)height *0.75f )-(float)width/4,(float)width/4,(float)width/4,0,90);
outline.AddLine((float)width-(float)width/8,((float)height*0.75f),(float)width/8 +((float)width/4),((float)height*0.75f));
outline.AddLine((float)width/8 +((float)width/4),(float)height*0.75f,(float)width/8 +((float)width/8),(float)height);
outline.AddLine((float)width/8 +((float)width/8),(float)height,(float)width/8 +((float)width/8),((float)height*0.75f));
outline.AddLine((float)width/8 +((float)width/8),((float)height*0.75f),(float)width/8,((float)height*0.75f));
outline.AddArc(0,((float)height*0.75f)-(float)width/4,(float)width/4,(float)width/4,90,90);
outline.AddLine(0,((float)height*0.75f)-(float)width/8,0,(float)width/8);
break;
case ShapeType.BallonSE:
outline.AddArc(0,0,(float)width/4,(float)width/4,180,90);
outline.AddLine((float)width/8,0,(float)width-(float)width/8,0);
outline.AddArc((float)width-(float)width/4,0,(float)width/4,(float)width/4,270,90);
outline.AddLine((float)width,(float)width/8,(float)width,((float)height*0.75f)-(float)width /8);
outline.AddArc((float)width-(float)width/4,((float)height *0.75f )-(float)width/4,(float)width/4,(float)width/4,0,90);
outline.AddLine((float)width-(float)width/8,((float)height*0.75f),(float)width-((float)width/4),((float)height*0.75f));
outline.AddLine((float)width-((float)width/4),(float)height*0.75f,(float)width-((float)width/4),(float)height);
outline.AddLine((float)width-((float)width/4),(float)height,(float)width -(3*(float)width/8),((float)height*0.75f));
outline.AddLine((float)width -(3*(float)width/8),((float)height*0.75f),(float)width/8,((float)height*0.75f));
outline.AddArc(0,((float)height*0.75f)-(float)width/4,(float)width/4,(float)width/4,90,90);
outline.AddLine(0,((float)height*0.75f)-(float)width/8,0,(float)width/8);
break;
case ShapeType.BallonNW:
outline.AddArc((float)width-(float)width/4,((float)height )-(float)width/4,(float)width/4,(float)width/4,0,90);
outline.AddLine((float)width-(float)width/8,((float)height),(float)width-((float)width/4),((float)height));
outline.AddArc(0,((float)height)-(float)width/4,(float)width/4,(float)width/4,90,90);
outline.AddLine(0,((float)height)-(float)width/8,0,(float)height *0.25f+(float)width/8);
outline.AddArc(0,(float)height *0.25f,(float)width/4,(float)width/4,180,90);
outline.AddLine((float)width/8,(float)height *0.25f,(float)width/4,(float)height *0.25f);
outline.AddLine((float)width/4,(float)height *0.25f,(float)width/4,0);
outline.AddLine((float)width/4,0,3*(float)width/8 ,(float)height *0.25f);
outline.AddLine(3*(float)width/8 ,(float)height *0.25f,(float)width -(float)width/8,(float)height *0.25f);
outline.AddArc((float)width-(float)width/4,(float)height *0.25f,(float)width/4,(float)width/4 ,270,90);
outline.AddLine((float)width,(float)width/8+(float)height *0.25f,(float)width,((float)height)-(float)width /8);
break;
case ShapeType.BallonNE:
outline.AddArc((float)width-(float)width/4,((float)height )-(float)width/4,(float)width/4,(float)width/4,0,90);
outline.AddLine((float)width-(float)width/8,((float)height),(float)width-((float)width/4),((float)height));
outline.AddArc(0,((float)height)-(float)width/4,(float)width/4,(float)width/4,90,90);
outline.AddLine(0,((float)height)-(float)width/8,0,(float)height *0.25f+(float)width/8);
outline.AddArc(0,(float)height *0.25f,(float)width/4,(float)width/4,180,90);
outline.AddLine((float)width/8,(float)height *0.25f,5*(float)width/8,(float)height *0.25f);
outline.AddLine(5*(float)width/8,(float)height *0.25f,3*(float)width/4,0);
outline.AddLine(3*(float)width/4,0,3*(float)width/4 ,(float)height *0.25f);
outline.AddLine(3*(float)width/4 ,(float)height *0.25f,(float)width -(float)width/8,(float)height *0.25f);
outline.AddArc((float)width-(float)width/4,(float)height *0.25f,(float)width/4,(float)width/4 ,270,90);
outline.AddLine((float)width,(float)width/8+(float)height *0.25f,(float)width,((float)height)-(float)width /8);
break;
default:break;
}
}
protected override void OnResize(EventArgs e)
{
if (this.Width < 2 * _borderwidth)
{
this.Width = 2 * _borderwidth;
return;
}
if (this.Height < 2 * _borderwidth)
{
this.Height = 2 * _borderwidth;
return;
}
// if (this.Width <= 0 || this.Height <= 0) return;
if (_bm == null)
{
_outline = new GraphicsPath();
updateOutline(ref _outline, _shape, this.Width, this.Height,this.BorderWidth);
}
else
{
Bitmap bm = (Bitmap)_bm.Clone();
Bitmap bm2 = new Bitmap(Width, Height);
// System.Diagnostics.Debug.WriteLine(bm2.Width + "," + bm2.Height);
Graphics g = Graphics.FromImage(bm2);
Matrix _m = new Matrix();
if(_shapeimagerotation!=0)
{
_m.RotateAt(_shapeimagerotation, new PointF(this.Width / 2, this.Height / 2));
// g.Transform = _m;
}
// Graphics.FromImage(bm2).DrawImage(bm, new RectangleF(0, 0, bm2.Width, bm2.Height), new RectangleF(0, 0, bm.Width, bm.Height), GraphicsUnit.Pixel);
g.DrawImage(bm, new RectangleF(0, 0, bm2.Width, bm2.Height), new RectangleF(0, 0, bm.Width, bm.Height), GraphicsUnit.Pixel);
TraceOutline.CTraceOuline trace = new TraceOutline.CTraceOuline();
string s = trace.TraceOutlineN(bm2, 0, bm2.Height / 2, bm2.Width / 2, Color.Black, Color.White, true, 1);
if (s == "") return;
Point[] p = trace.StringOutline2Polygon(s);
_outline = new GraphicsPath();
_outline.AddPolygon(p);
_outline.Transform(_m);
if (_bmtexture != null)
{
g.Transform = _m;
g.DrawImage(_bmtexture, new RectangleF(0, 0, bm2.Width, bm2.Height), new RectangleF(0, 0, _bmtexture.Width, _bmtexture.Height), GraphicsUnit.Pixel);
}
g.Dispose();
if (_bmtexture != null)
{
this.BackgroundImage = bm2;
}
else
{
this.BackgroundImage = null;
this.Refresh();
}
this.Region = new Region(_outline);
}
if (_outline != null && _bm==null)
{
//these require widening
if (
this.Shape == ShapeType.LineDown ||
this.Shape == ShapeType.LineUp ||
this.Shape == ShapeType.LineHorizontal ||
this.Shape == ShapeType.LineVertical ||
this.Shape == ShapeType.Rectangle
)
{
//border width to widen by
int bw = (this.Shape == ShapeType.Rectangle) ? 1 : _borderwidth;
GraphicsPath tmpoutline = (GraphicsPath)_outline.Clone();
Pen p = new Pen(_bordercolor, bw);
//line is always generated from left to right
//defaults no direction caps
//leftmost or topmost for vertical line
p.StartCap = LineCap.Round;
//rigtmost or bottommost for vertical line
p.EndCap = LineCap.Round;
if (_direction != LineDirection.None)
switch (this.Shape)
{
//case ShapeType.LineHorizontal:
// //
// if (_direction == LineDirection.LeftDown || _direction == LineDirection.LeftUp)
// p.StartCap = LineCap.ArrowAnchor;
// else
// p.EndCap = LineCap.ArrowAnchor;
// break;
case ShapeType.LineVertical:
if (_direction == LineDirection.LeftUp || _direction == LineDirection.RightUp)
p.StartCap = LineCap.ArrowAnchor;
else
p.EndCap = LineCap.ArrowAnchor;
break;
case ShapeType.LineHorizontal:
case ShapeType.LineUp:
case ShapeType.LineDown:
if (_direction == LineDirection.LeftUp || _direction == LineDirection.LeftDown)
p.StartCap = LineCap.ArrowAnchor;
else
p.EndCap = LineCap.ArrowAnchor;
break;
}
try
{
tmpoutline.Widen(p);
}
catch {
}
if (this.Shape != ShapeControl.ShapeType.Rectangle)
{
//widen region
this.Region = new Region(tmpoutline);
//original region
Region org = new Region(_outline);
//add up both
this.Region.Union(org);
}
else
{
_outline.AddPath(tmpoutline, true);
_outline.CloseAllFigures();
this.Region = new Region(_outline);
}
}
else
{
this.Region = new Region(_outline);
}
}
this.Refresh();
base.OnResize (e);
}
protected override void OnPaint(PaintEventArgs pe)
{
//Rendering with Gradient
if (_usegradient)
{
try
{
PathGradientBrush br = new PathGradientBrush(this._outline);
br.CenterColor = this._centercolor;
br.SurroundColors = new Color[] { this._surroundcolor };
pe.Graphics.FillPath(br, this._outline);
}
catch { }
}
//Rendering with Border
if(_borderwidth>0)
{
Pen p=new Pen(_bordercolor,_borderwidth*2);
//setting for lines
if (this.Shape == ShapeType.LineDown ||
this.Shape == ShapeType.LineUp ||
this.Shape == ShapeType.LineHorizontal ||
this.Shape == ShapeType.LineVertical)
{
p = new Pen(_bordercolor, _borderwidth);
p.StartCap = LineCap.Round;
p.EndCap = LineCap.Round;
if (_direction != LineDirection.None)
switch (this.Shape)
{
//case ShapeType.LineHorizontal:
// if (_direction == LineDirection.LeftDown || _direction == LineDirection.LeftUp)
// p.StartCap = LineCap.ArrowAnchor;
// else
// p.EndCap = LineCap.ArrowAnchor;
// break;
case ShapeType.LineVertical:
if (_direction == LineDirection.LeftUp || _direction == LineDirection.RightUp)
p.StartCap = LineCap.ArrowAnchor;
else
p.EndCap = LineCap.ArrowAnchor;
break;
case ShapeType.LineHorizontal:
case ShapeType.LineUp:
case ShapeType.LineDown:
if (_direction == LineDirection.LeftUp || _direction == LineDirection.LeftDown )
p.StartCap = LineCap.ArrowAnchor;
else
p.EndCap = LineCap.ArrowAnchor;
break;
}
}
//set border style
p.DashStyle=_borderstyle;
if (p.DashStyle == DashStyle.Custom)
p.DashPattern = new float[] { 1, 1,1,1 };
//animate border by using a one of sequence of 10 generated dash style with every call
if(this.AnimateBorder)
{
p.DashStyle =DashStyle.Custom;
_static_ds = (_static_ds++) % 10;
p.DashPattern = this._btoggled ? new float[] { 1, 0.01f+0.05f * _static_ds, 1, 1, 1 } : new float[] { 1, 1, 1, 1 };
}
pe.Graphics.SmoothingMode=SmoothingMode.HighQuality;
pe.Graphics.DrawPath(p,this._outline);
p.Dispose();
}
//Rendering the text to be at the center of the shape
StringFormat sf=new StringFormat();
sf.Alignment=StringAlignment.Center;
sf.LineAlignment=StringAlignment.Center;
switch(_shape)
{
case ShapeType.BallonNE:
case ShapeType.BallonNW:
pe.Graphics.DrawString(this.Text,this.Font,new SolidBrush(this.ForeColor),new RectangleF(0,this.Height*0.25f,this.Width ,this.Height*0.75f),sf);
break;
case ShapeType.BallonSE:
case ShapeType.BallonSW:
pe.Graphics.DrawString(this.Text,this.Font,new SolidBrush(this.ForeColor),new RectangleF(0,0,this.Width ,this.Height*0.75f),sf);
break;
default:
pe.Graphics.DrawString(this.Text,this.Font,new SolidBrush(this.ForeColor),new Rectangle(0,0,this.Width ,this.Height),sf);
break;
}
// Calling the base class OnPaint
base.OnPaint(pe);
}
private void ShapeControl_TextChanged(object sender, System.EventArgs e)
{
this.Refresh();
}
private void timer1_Tick(object sender, EventArgs e)
{
this.Visible = !this.Visible;
}
private void timer2_Tick(object sender, EventArgs e)
{
if (!_vibrate) return;
_voffseted = !_voffseted;
this.Top =_voffseted ?this.Top -5:this.Top +5;
}
private void timer3_Tick(object sender, EventArgs e)
{
this.Refresh();
_btoggled = !_btoggled;
}
public static bool SaveToFile(ShapeControl.CustomControl1 ctrl1, string filename, bool bFromDesigner)
{
string path = "";
try
{
if (filename.Length < 8) return false; //min name .shp.jpg
if (filename.ToUpper().IndexOf(".SHP.JPG") != (filename.Length - 8)) return false;
if (filename != "")
{
if (filename.IndexOf("\\") >= 0)
path = filename;
else
path = Application.UserAppDataPath + "\\" + filename;
if (bFromDesigner)
{
if (MessageBox.Show("Save to " + path, "Confirm", MessageBoxButtons.OKCancel) != DialogResult.OK)
return false;
}
string shapepath = path.Substring(0, path.Length - 4);
if (File.Exists(path))
{
if (bFromDesigner)
{
if (MessageBox.Show(path + " already exist. Overwrite", "Confirm", MessageBoxButtons.OKCancel) != DialogResult.OK)
return false;
}
File.Delete(path);
if (File.Exists(shapepath))
File.Delete(shapepath);
}
if (!File.Exists(shapepath))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(shapepath))
{
sw.WriteLine("AnimateBorder<" + ctrl1.AnimateBorder.ToString()+">");
sw.WriteLine("Vibrate<" + ctrl1.Vibrate.ToString() + ">");
sw.WriteLine("Blink<" + ctrl1.Blink.ToString() + ">");
sw.WriteLine("BackColor<" + ctrl1.BackColor.ToArgb() + ">");
sw.WriteLine("BorderColor<" + ctrl1.BorderColor.ToArgb() + ">");
sw.WriteLine("BorderColor<" + ctrl1.BorderColor.ToArgb() + ">");
sw.WriteLine("BorderStyle<" + ctrl1.BorderStyle.ToString() + ">");
sw.WriteLine("BorderWidth<" + ctrl1.BorderWidth + ">");
sw.WriteLine("CenterColor<" + ctrl1.CenterColor.ToArgb() + ">");
sw.WriteLine("Connector<" + ctrl1.Connector + ">");
sw.WriteLine("Direction<" + ctrl1.Direction + ">");
sw.WriteLine("Font<Name:" + ctrl1.Font.FontFamily.Name + ",Size:" + ctrl1.Font.Size + ",Style:" + ctrl1.Font.Style +
",GraphicalUnits:" + ctrl1.Font.Unit + ">");
sw.WriteLine("Shape<" + ctrl1.Shape.ToString() + ">");
if (ctrl1.ShapeImage != null)
{
//sw.WriteLine("ShapeImage>shapeimage.jpg");
//ctrl1.ShapeImage.Save(path + ".shapeimage.jpg",
// System.Drawing.Imaging.ImageFormat.Jpeg);
sw.WriteLine("ShapeImage<" + BitmapToBase64String((Bitmap)ctrl1.ShapeImage) + ">");
}
else sw.WriteLine("ShapeImage<null>");
sw.WriteLine("ShapeImageRotation<" + ctrl1.ShapeImageRotation + ">");
if (ctrl1.ShapeImageTexture != null)
{
//sw.WriteLine("ShapeImageTexture>shapeimagetexture.jpg");
//ctrl1.ShapeImageTexture.Save(path + ".shapeimagetexture.jpg",
// System.Drawing.Imaging.ImageFormat.Jpeg);
sw.WriteLine("ShapeImageTexture<" + BitmapToBase64String((Bitmap)ctrl1.ShapeImageTexture) + ">");
}
else sw.WriteLine("ShapeImageTexture<null>");
sw.WriteLine("SurroundColor<" + ctrl1.SurroundColor.ToArgb() + ">");
sw.WriteLine("UseGradient<" + ctrl1.UseGradient.ToString() + ">");
sw.WriteLine("ForeColor<" + ctrl1.ForeColor.ToArgb() + ">");
sw.WriteLine("Text<" + ctrl1.Text.ToString() + ">");
sw.WriteLine("Width<" + ctrl1.Width + ">");
sw.WriteLine("Height<" + ctrl1.Height + ">");
if (ctrl1.BackgroundImage == null)
sw.WriteLine("BackgroundImage<null>");
else
{
//sw.WriteLine("BackgroundImage>backgroundimage.jpg");
//ctrl1.BackgroundImage.Save(path + ".backgroundimage.jpg",
// System.Drawing.Imaging.ImageFormat.Jpeg);
sw.WriteLine("BackgroundImage<" + BitmapToBase64String((Bitmap)ctrl1.BackgroundImage) + ">");
}
Bitmap bm=new Bitmap(ctrl1.Width ,ctrl1.Height,System.Drawing.Imaging.PixelFormat.Format32bppArgb );
Bitmap mask =(Bitmap) bm.Clone();
Graphics g = Graphics.FromImage(mask);
g.FillRectangle(new SolidBrush(Color.Black), 0, 0, mask.Width, mask.Height);
Region maskregion = ctrl1.Region;//new Region(ctrl1._outline);
g.FillRegion(new SolidBrush(Color.White), maskregion);
g.Dispose();
//for debugging purpose
//mask.Save(path + ".mask.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
ctrl1.DrawToBitmap(bm, ctrl1.ClientRectangle);
// bm.Save(path + ".bm.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
Bitmap bmout = CBitmapOps.DoBitOpsForBitmap(bm, mask, "AND");
CBitmapOps.DoInvertBitmap(mask);
//mask.Save(path + ".mask_inv.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
bmout = CBitmapOps.DoBitOpsForBitmap(bmout, mask, "OR");
// bmout.Save(path + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
bmout.Save(path , System.Drawing.Imaging.ImageFormat.Jpeg);
if (bFromDesigner)
MessageBox.Show("Shape saved to " + path);
}
} //if
} //if
} //try
catch (Exception e)
{
if (bFromDesigner)
MessageBox.Show(e.ToString());
return false;
}
return true;
}
private static string UnicodeToHex(string uni)
{
return "";
}
private static string BitmapToBase64String(Bitmap bm)
{
using( MemoryStream ms = new MemoryStream())
{
bm.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] bms = ms.GetBuffer();
ms.Close();
ms.Dispose();
string b64str = Convert.ToBase64String(bms);
return b64str;
}
}
private static Bitmap BitmapFromBase64String(string b64str)
{
byte[] b = Convert.FromBase64String(b64str);
using (MemoryStream ms = new MemoryStream(b))
{
Bitmap bm = (Bitmap)Bitmap.FromStream(ms);
return bm;
}
}
public static bool LoadFromFile(ShapeControl.CustomControl1 ctrl1, string filename,bool bFromDesigner)
{
try
{
if (filename != "")
{
if (filename.Length < 8) return false; //min name .shp.jpg
if (filename.ToUpper().IndexOf(".SHP.JPG") != (filename.Length - 8)) return false;
if (bFromDesigner)
{
if (MessageBox.Show("Load from " + filename, "Confirm", MessageBoxButtons.OKCancel) != DialogResult.OK)
return false;
}
//remove the .jpg to get the .shp filename
string shapefilename = filename.Substring(0, filename.Length - 4);
var v = System.IO.File.ReadAllLines(shapefilename);
for (int i = 0; i < v.Length; i++)
{
// var v1 = v[i].Split('>');
//find first "<"
int startindex = v[i].IndexOf("<");
int endindex = v[i].LastIndexOf(">");
var v1 = new string[2];
if ((endindex > 0) && (startindex > 0) && (endindex > startindex))
{
v1[0] = v[i].Substring(0, startindex ); //last char before <
v1[1] = v[i].Substring(startindex+1); //from char after <
v1[1] = v1[1].Substring(0, v1[1].Length - 1); //remove >
}
else
continue;
switch (v1[0])
{
case "BackgroundImage":
if (v1[1] == "null")
{
ctrl1.BackgroundImage = null;
}
else
{
//using (var bmpTemp = new Bitmap(filename + "." + v1[1]))
//{
// ctrl1.BackgroundImage = new Bitmap(bmpTemp);
//}
using (var bmpTemp =BitmapFromBase64String(v1[1]))
{
ctrl1.BackgroundImage = new Bitmap(bmpTemp);
}
}
break;
case "ShapeImage":
if (v1[1] == "null")
{
ctrl1.ShapeImage = null;
}
else
{
//using (var bmpTemp = new Bitmap(filename + "." + v1[1]))
//{
// ctrl1.ShapeImage = new Bitmap(bmpTemp);
//}
using (var bmpTemp = BitmapFromBase64String(v1[1]))
{
ctrl1.ShapeImage = new Bitmap(bmpTemp);
}
}
break;
case "Shape":
ctrl1.Shape = (ShapeControl.ShapeType)Enum.Parse(typeof(ShapeControl.ShapeType), v1[1], true);
break;
case "ForeColor":
ctrl1.ForeColor = Color.FromArgb(int.Parse(v1[1]));
break;
case "Text":
ctrl1.Text = v1[1];
break;
case "BorderColor":
ctrl1.BorderColor = Color.FromArgb(int.Parse(v1[1]));
break;
case "AnimateBorder":
ctrl1.AnimateBorder = bool.Parse(v1[1]); break;
case "BackColor":
ctrl1.BackColor = Color.FromArgb(int.Parse(v1[1]));
break;
case "BorderWidth":
ctrl1.BorderWidth = int.Parse(v1[1]);
break;
case "BorderStyle":
ctrl1.BorderStyle = (System.Drawing.Drawing2D.DashStyle)Enum.Parse(typeof(System.Drawing.Drawing2D.DashStyle), v1[1]);
break;
case "CenterColor":
ctrl1.CenterColor = Color.FromArgb(int.Parse(v1[1]));
break;
case "SurroundColor":
ctrl1.SurroundColor = Color.FromArgb(int.Parse(v1[1]));
break;
case "Connector":
ctrl1.Connector = (ShapeControl.ConnecterType)Enum.Parse(typeof(ShapeControl.ConnecterType), v1[1], true);
break;
case "Direction":
ctrl1.Direction = (ShapeControl.LineDirection)Enum.Parse(typeof(ShapeControl.LineDirection), v1[1], true);
break;
case "Font":
var v2 = v1[1].Split(',');
string familyname = "Arial";
float size = 8f;
GraphicsUnit gu = GraphicsUnit.Point;
FontStyle fs = FontStyle.Regular;
for (int j = 0; j < v2.Length; j++)
{
var v3 = v2[j].Trim().Split(':');
switch (v3[0].Trim())
{
case "Name": familyname = v3[1]; break;
case "Size": size = float.Parse(v3[1]); break;
case "GraphicalUnits":
gu = (GraphicsUnit)Enum.Parse(typeof(GraphicsUnit), v3[1], true);
break;
case "Style":
fs = (FontStyle)Enum.Parse(typeof(FontStyle), v3[1], true);
break;
}
}
ctrl1.Font = new Font(familyname, size, fs, gu);
break;
case "UseGradient":
ctrl1.UseGradient = bool.Parse(v1[1]);
break;
case "ShapeImageRotation":
ctrl1.ShapeImageRotation = int.Parse(v1[1]);
break;
case "ShapeImageTexture":
if (v1[1] == "null")
{
ctrl1.ShapeImageTexture = null;
}
else
{
//using (var bmpTemp = new Bitmap(filename + "." + v1[1]))
//{
// ctrl1.ShapeImageTexture = new Bitmap(bmpTemp);
//}
using (var bmpTemp = BitmapFromBase64String(v1[1]))
{
ctrl1.ShapeImageTexture = new Bitmap(bmpTemp);
}
}
break;
case "Width":
ctrl1.Width = int.Parse(v1[1]);
break;
case "Height":
ctrl1.Height = int.Parse(v1[1]);
break;
}
}
}
}
catch (Exception e)
{ if(bFromDesigner )
MessageBox.Show(e.ToString());
return false;
}
return true;
}
}
public class Line
{
public static void setConnectors(ref ShapeControl.CustomControl1 ctrl1, ref ShapeControl.CustomControl1 ctrl2)
{
//defaults
ctrl1.Connector = ShapeControl.ConnecterType.Center;
ctrl2.Connector = ShapeControl.ConnecterType.Center;
int maxwidth = (ctrl1.Width > ctrl2.Width) ? ctrl1.Width : ctrl2.Width;
int maxheight = (ctrl1.Height > ctrl2.Height) ? ctrl1.Height : ctrl2.Height;
//check y delta
int ydelta = ctrl1.Top - ctrl2.Top;
int xdelta = ctrl1.Left - ctrl2.Left;
//overlapped
if (Math.Abs(ydelta) < maxheight && Math.Abs(xdelta) < maxwidth) return;
if (Math.Abs(ydelta) > Math.Abs(xdelta)) //use top and bottom connector
{
if (ydelta > 0) //ctrl1 is lower
{
ctrl1.Connector = ShapeControl.ConnecterType.Top;
ctrl2.Connector = ShapeControl.ConnecterType.Bottom;
}
else
{
ctrl1.Connector = ShapeControl.ConnecterType.Bottom;
ctrl2.Connector = ShapeControl.ConnecterType.Top;
}
}
else //use left and right connector
{
if (xdelta > 0) // ctrl1 on the right
{
ctrl1.Connector = ShapeControl.ConnecterType.Left;
ctrl2.Connector = ShapeControl.ConnecterType.Right;
}
else
{
ctrl1.Connector = ShapeControl.ConnecterType.Right;
ctrl2.Connector = ShapeControl.ConnecterType.Left;
}
}
}
public static void setConnectorPoint(ref int x, ref int y, ShapeControl.CustomControl1 ctrl)
{
int x0 = ctrl.Location.X;
int y0 = ctrl.Location.Y;
int x0delta = 0, y0delta = 0;
switch (ctrl.Connector)
{
case ShapeControl.ConnecterType.Left:
y0delta = ctrl.Height / 2;
break;
case ShapeControl.ConnecterType.Right:
x0delta = ctrl.Width;
y0delta = ctrl.Height / 2;
break;
case ShapeControl.ConnecterType.Top:
x0delta = ctrl.Width / 2;
break;
case ShapeControl.ConnecterType.Bottom:
x0delta = ctrl.Width / 2;
y0delta = ctrl.Height;
break;
case ShapeControl.ConnecterType.Center:
x0delta = ctrl.Width / 2;
y0delta = ctrl.Height / 2;
break;
}
x = x0 + x0delta;
y = y0 + y0delta;
}
//generic
//can be used for any line shape control
//x0,y0 is source pt, x1,y1 is the dest point
//for directional line, the arrow would appear in x1,y1
public static void setLine(ref ShapeControl.CustomControl1 ctrl1, int x0, int y0, int x1, int y1)
{
int xx0 = 0; //left
int yy0 = 0; //top
int xx1 = 0; //right
int yy1 = 0; //bottom
//set direction based on location of dest_cm in relation to src_cam
if (x0 <= x1) // dest on the right
{
if (ctrl1.Direction != ShapeControl.LineDirection.None)
{
if (y0 < y1) // dest_cam at the bottom
ctrl1.Direction = ShapeControl.LineDirection.RightDown;
else
ctrl1.Direction = ShapeControl.LineDirection.RightUp;
}
//left src
xx0 = x0;
yy0 = y0;
//right dest
xx1 = x1;
yy1 = y1;
}
else //dest on the left
{
if (ctrl1.Direction != ShapeControl.LineDirection.None)
{
if (y0 < y1) //dest_cam at the bottom
ctrl1.Direction = ShapeControl.LineDirection.LeftDown;
else
ctrl1.Direction = ShapeControl.LineDirection.LeftUp;
}
//left dest
xx0 = x1;
yy0 = y1;
//right src
xx1 = x0;
yy1 = y0;
}
float gradient = 0f;
//check for vert and horizontal line
if (Math.Abs(xx0 - xx1) <= 0 || Math.Abs(yy0 - yy1) <= 0)
{
ctrl1.Shape = (Math.Abs(xx0 - xx1) <= 0) ?
ShapeControl.ShapeType.LineVertical :
ShapeControl.ShapeType.LineHorizontal;
} //normal line
else
{
gradient = (float)(yy0 - yy1) / (float)(xx0 - xx1);
ctrl1.Shape = (gradient > 0f) ? ShapeControl.ShapeType.LineDown : ShapeControl.ShapeType.LineUp;
}
//all shape control are specified by
//the top-left corner, width and height
//lx0,ly0 : location for top-left of shape control
//lx1,ly1 : location for bottom-right of shape control
//lw: width of shape control
//lh: height of shape control
int lx0 = 0, ly0 = 0, lx1 = 0, ly1 = 0, lw = 0, lh = 0;
//offset from to cater for line width
int delta = (4 * ctrl1.BorderWidth) / 4;
switch (ctrl1.Shape)
{
case ShapeControl.ShapeType.LineVertical:
lx0 = xx0 - delta;
lx1 = xx1 + delta;
ly0 = yy0 - delta;
ly1 = yy1 + delta;
lw = Math.Abs(lx0 - lx1);
lh = Math.Abs(ly0 - ly1);
break;
case ShapeControl.ShapeType.LineHorizontal:
ly0 = yy0 - delta;
ly1 = yy1 + delta;
lx0 = xx0 - delta;
lx1 = xx1 + delta;
lh = Math.Abs(ly0 - ly1);
lw = Math.Abs(lx0 - lx1);
break;
case ShapeControl.ShapeType.LineUp:
lx0 = xx0 - delta;
ly0 = yy1 - delta;
lx1 = xx1 + delta;
ly1 = yy0 + delta;
lw = Math.Abs(lx0 - lx1);
lh = Math.Abs(ly0 - ly1);
break;
case ShapeControl.ShapeType.LineDown:
lx0 = xx0 - delta;
ly0 = yy0 - delta;
lx1 = xx1 + delta;
ly1 = yy1 + delta;
lw = Math.Abs(lx0 - lx1);
lh = Math.Abs(ly0 - ly1);
break;
}
//set the location and sie of the line shape control
ctrl1.Size = new System.Drawing.Size(lw, lh);
ctrl1.Location = new Point(lx0, ly0);
}
}
}