using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using SmartDialAgent.Utils;
using System.Drawing.Drawing2D;
namespace SmartDialAgent.Controls
{
public class PictureBoxSelector : System.Windows.Forms.Control
{
private Color _BorderColor = new Color();
//private Color _BackColor = new Color();
private bool _ReSizeble;
private Point _SelfLocation = new Point();
private Point _MouseLocation = new Point();
private int _SelfWidth;
private int _SelfHeight;
private int _SelectSelctedIndex;//0-8,0:SizeAll
private Rectangle _rectLeftSelector = new Rectangle();
private Rectangle _rectTopSelector = new Rectangle();
private Rectangle _rectRightSelector = new Rectangle();
private Rectangle _rectBottomSelector = new Rectangle();
private Rectangle _rectLeftTopSelector = new Rectangle();
private Rectangle _rectRightTopSelector = new Rectangle();
private Rectangle _rectRightBottomSelector = new Rectangle();
private Rectangle _rectLeftBottomSelector = new Rectangle();
private System.ComponentModel.Container components = null;
public PictureBoxSelector()
{
InitializeComponent();
}
[DefaultValue("Black"), Description("color of the border"), Category("Appearance")]
public Color BorderColor
{
get
{
// Insert code here.
return _BorderColor;
}
set
{
_BorderColor = value;
this.Invalidate();
}
}
//[DefaultValue("Control"), Description("Background color"), Category("Appearance")]
//public override Color BackColor
//{
// get
// {
// // Insert code here.
// return _BackColor;
// }
// set
// {
// _BackColor = value;
// this.Invalidate();
// }
//}
[DefaultValue(false), Description("Indicates the control coud be moved and resized"), Category("Behavior")]
public bool ReSizeble
{
get
{
// Insert code here.
return _ReSizeble;
}
set
{
_ReSizeble = value;
this.Invalidate();
}
}
[Description("Selected area"), Category("Behavior")]
public Rectangle SelectedRectangle
{
get
{
Rectangle selectRectangler = new Rectangle();
selectRectangler.X = this.Location.X ;
selectRectangler.Y = this.Location.Y ;
selectRectangler.Height = this.Height ;
selectRectangler.Width = this.Width ;
return selectRectangler;
}
}
///
/// the selected image
///
public Image SelectedImage { get; private set; }
public static Bitmap Crop(Image image, Size targetSize, int x, int y)
{
try
{
Bitmap bmp = new Bitmap(targetSize.Width, targetSize.Height);//, PixelFormat.Format24bppRgb);
bmp.SetResolution(image.HorizontalResolution, image.VerticalResolution);
Graphics gfx = Graphics.FromImage(bmp);
gfx.SmoothingMode = SmoothingMode.AntiAlias;
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(image, new Rectangle(0, 0, targetSize.Width, targetSize.Height),
x, y, targetSize.Width, targetSize.Height, GraphicsUnit.Pixel);
gfx.Dispose();
return bmp;
}
catch (Exception)
{
return null;
}
}
///
/// repaint the background by copying crop image from parent picturebox
///
///
private void RepaintBackground(PaintEventArgs e)
{
if (PictureBox != null && PictureBox.Image!=null)
{
Image img = Crop(PictureBox.Image, Size, Left - PictureBox.Left, Top - PictureBox.Top);
if (img != null)
e.Graphics.DrawImage(img, 0, 0, Width, Height);
SelectedImage = img;
}
}
protected override void OnPaint(PaintEventArgs e)
{
RepaintBackground(e);
ReDrawControl(e.Graphics);
}
private void DrawSelector(Graphics graphics)
{
SolidBrush SelectorPen = new SolidBrush(Color.White);
Pen borderPen = new Pen(this._BorderColor, 1);
try
{
//solid
PointF[] LeftPoints = getPointF(0, this.Height / 2 - 3, 6, 6);
graphics.FillClosedCurve(SelectorPen, LeftPoints);
PointF[] TopPoints = getPointF(this.Width / 2 - 3, 0, 6, 6);
graphics.FillClosedCurve(SelectorPen, TopPoints);
PointF[] RightPoints = getPointF(this.Width - 7, this.Height / 2 - 3, 6, 6);
graphics.FillClosedCurve(SelectorPen, RightPoints);
PointF[] BottomPoints = getPointF(this.Width / 2 - 3, this.Height - 7, 6, 6);
graphics.FillClosedCurve(SelectorPen, BottomPoints);
//remove the 4 solid resize selectors, I don't need it, if you need to, add them back
//PointF[] LeftTopPoints = getPointF(0, 0, 6, 6);
//graphics.FillClosedCurve(SelectorPen, LeftTopPoints);
//PointF[] RightTopPoints = getPointF(this.Width - 7, 0, 6, 6);
//graphics.FillClosedCurve(SelectorPen, RightTopPoints);
//PointF[] RightBottomPoints = getPointF(this.Width - 7, this.Height - 7, 6, 6);
//graphics.FillClosedCurve(SelectorPen, RightBottomPoints);
//PointF[] LeftBottomPoints = getPointF(0, this.Height - 7, 6, 6);
//graphics.FillClosedCurve(SelectorPen, LeftBottomPoints);
//borders
int border = 6;
_rectLeftSelector.X = 0;
_rectLeftSelector.Y = this.Height / 2 - 3;
_rectLeftSelector.Height = border;
_rectLeftSelector.Width = border;
graphics.DrawRectangle(borderPen, _rectLeftSelector);
_rectTopSelector.X = this.Width / 2 - 3;
_rectTopSelector.Y = 0;
_rectTopSelector.Height = border;
_rectTopSelector.Width = border;
graphics.DrawRectangle(borderPen, _rectTopSelector);
_rectRightSelector.X = this.Width - 7;
_rectRightSelector.Y = this.Height / 2 - 3;
_rectRightSelector.Height = border;
_rectRightSelector.Width = border;
graphics.DrawRectangle(borderPen, _rectRightSelector);
_rectBottomSelector.X = this.Width / 2 - 3;
_rectBottomSelector.Y = this.Height - 7;
_rectBottomSelector.Height = border;
_rectBottomSelector.Width = border;
graphics.DrawRectangle(borderPen, _rectBottomSelector);
//remove the 4 solid resize selectors, I don't need it, if you need to, add them back
//_rectLeftTopSelector.X = 0;
//_rectLeftTopSelector.Y = 0;
//_rectLeftTopSelector.Width = border;
//_rectLeftTopSelector.Height = border;
//graphics.DrawRectangle(borderPen, _rectLeftTopSelector);
//_rectRightTopSelector.X = this.Width - 7;
//_rectRightTopSelector.Y = 0;
//_rectRightTopSelector.Width = border;
//_rectRightTopSelector.Height = border;
//graphics.DrawRectangle(borderPen, _rectRightTopSelector);
//_rectRightBottomSelector.X = this.Width - 7;
//_rectRightBottomSelector.Y = this.Height - 7;
//_rectRightBottomSelector.Width = border;
//_rectRightBottomSelector.Height = border;
//graphics.DrawRectangle(borderPen, _rectRightBottomSelector);
//_rectLeftBottomSelector.X = 0;
//_rectLeftBottomSelector.Y = this.Height - 7;
//_rectLeftBottomSelector.Width = border;
//_rectLeftBottomSelector.Height = border;
//graphics.DrawRectangle(borderPen, _rectLeftBottomSelector);
}
catch (Exception E)
{
throw E;
}
finally
{
SelectorPen.Dispose();
borderPen.Dispose();
}
}
private void ReDrawControl(Graphics graphics)
{
try
{
//draw background
//graphics.Clear(this._BackColor);
//SolidBrush backPen=new SolidBrush(this._BackColor);
//PointF point1 = new PointF(1,1);
//PointF point2 = new PointF(this.Width-2,1);
//PointF point3 = new PointF(this.Width-2,this.Height-2);
//PointF point4 = new PointF(1,this.Height-2);
//PointF[] points = {point1, point2, point3, point4};
//graphics.DrawImage(ImageUtils.CropImage(this.PictureBox, new Rectangle(Left, Top, Width, Height)),);
//graphics.FillClosedCurve(backPen, points);
//border
Rectangle rectBorder = new Rectangle();
Pen borderPen = new Pen(this._BorderColor, 1);
rectBorder.X = 0;
rectBorder.Y = 0;
rectBorder.Height = this.Height - 1;
rectBorder.Width = this.Width - 1;
graphics.DrawRectangle(borderPen, rectBorder);
//selector
if (_ReSizeble)
{
DrawSelector(graphics);
}
}
catch (Exception E)
{
throw E;
}
finally
{
graphics.Dispose();
}
}
public PictureBox PictureBox { get; set; }
protected override void OnPaintBackground(PaintEventArgs e)
{
this.RepaintBackground(e);
}
private PointF[] getPointF(int x, int y, int Width, int Height)
{
PointF point1 = new PointF(x, y);
PointF point2 = new PointF(x + Width, y);
PointF point3 = new PointF(x + Width, y + Height);
PointF point4 = new PointF(x, y + Height);
PointF[] points = { point1, point2, point3, point4 };
return points;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
#region generated by Visual Studio
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.Resize += new EventHandler(ShapeEx_Resize);
this.MouseDown += new MouseEventHandler(ShapeEx_MouseDown);
this.MouseMove += new MouseEventHandler(ShapeEx_MouseMove);
this.MouseLeave += new EventHandler(ShapeEx_MouseLeave);
this.MouseUp += new MouseEventHandler(ShapeEx_MouseUp);
this.Move += new EventHandler(Selection_Move);
this._BorderColor = Color.Black;
//this._BackColor = Color.Transparent;//.FromName("Control");
this._ReSizeble = false;
this._SelectSelctedIndex = -1;
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
//SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
#endregion
private void ShapeEx_Resize(object sender, EventArgs e)
{
//hard code 96, the smallest size could be,
//will be better if use a Size property
if (this.Width < 96 || this.Height < 96)
{
this.Width = 96;
this.Height = 96;
}
this.Invalidate();
}
private void ShapeEx_MouseDown(object sender, MouseEventArgs e)
{
if (_ReSizeble)
{
if (_rectLeftSelector.Contains(e.X, e.Y) || _rectRightSelector.Contains(e.X, e.Y) || _rectTopSelector.Contains(e.X, e.Y) || _rectBottomSelector.Contains(e.X, e.Y) || _rectLeftTopSelector.Contains(e.X, e.Y) || _rectRightTopSelector.Contains(e.X, e.Y) || _rectRightBottomSelector.Contains(e.X, e.Y) || _rectLeftBottomSelector.Contains(e.X, e.Y))
{
if (_rectLeftTopSelector.Contains(e.X, e.Y))
{
this.Cursor = Cursors.SizeNWSE;
this._SelectSelctedIndex = 1;
}
if (_rectTopSelector.Contains(e.X, e.Y))
{
this.Cursor = Cursors.SizeNS;
this._SelectSelctedIndex = 2;
}
if (_rectRightTopSelector.Contains(e.X, e.Y))
{
this.Cursor = Cursors.SizeNESW;
this._SelectSelctedIndex = 3;
}
if (_rectRightSelector.Contains(e.X, e.Y))
{
this.Cursor = Cursors.SizeWE;
this._SelectSelctedIndex = 4;
}
if (_rectRightBottomSelector.Contains(e.X, e.Y))
{
this.Cursor = Cursors.SizeNWSE;
this._SelectSelctedIndex = 5;
}
if (_rectBottomSelector.Contains(e.X, e.Y))
{
this.Cursor = Cursors.SizeNS;
this._SelectSelctedIndex = 6;
}
if (_rectLeftBottomSelector.Contains(e.X, e.Y))
{
this.Cursor = Cursors.SizeNESW;
this._SelectSelctedIndex = 7;
}
if (_rectLeftSelector.Contains(e.X, e.Y))
{
this.Cursor = Cursors.SizeWE;
this._SelectSelctedIndex = 8;
}
}
else
{
this.Cursor = Cursors.SizeAll;
this._SelectSelctedIndex = 0;
}
this._SelfLocation.X = this.Location.X;
this._SelfLocation.Y = this.Location.Y;
this._MouseLocation.X = Cursor.Position.X;
this._MouseLocation.Y = Cursor.Position.Y;
this._SelfWidth = this.Width;
this._SelfHeight = this.Height;
}
}
private void ShapeEx_MouseMove(object sender, MouseEventArgs e)
{
//move and resize
//since I removed 4 resize selector, it will only fall into cases like 2,4,6,8,etc
switch (this._SelectSelctedIndex)
{
case 0:
this.Location = new Point(Cursor.Position.X - (_MouseLocation.X - _SelfLocation.X), Cursor.Position.Y - (_MouseLocation.Y - _SelfLocation.Y));
break;
case 1:
this.Height = this._SelfHeight - (Cursor.Position.Y - _MouseLocation.Y);
this.Width = this._SelfWidth - (Cursor.Position.X - _MouseLocation.X);
this.Location = new Point(Cursor.Position.X - _MouseLocation.X + _SelfLocation.X, Cursor.Position.Y - _MouseLocation.Y + _SelfLocation.Y);
break;
case 2:
this.Height = this._SelfHeight - (Cursor.Position.Y - _MouseLocation.Y);
this.Width = Height;//remove if Width<> Height
this.Location = new Point(_SelfLocation.X, Cursor.Position.Y - _MouseLocation.Y + _SelfLocation.Y);
break;
case 3:
this.Height = this._SelfHeight - (Cursor.Position.Y - _MouseLocation.Y);
this.Width = this._SelfWidth + (Cursor.Position.X - _MouseLocation.X);
this.Location = new Point(_SelfLocation.X, Cursor.Position.Y - (_MouseLocation.Y - _SelfLocation.Y));
break;
case 4:
this.Width = this._SelfWidth + (Cursor.Position.X - _MouseLocation.X);
Height = Width;//remove if Width<> Height
break;
case 5:
this.Height = this._SelfHeight + (Cursor.Position.Y - _MouseLocation.Y);
this.Width = this._SelfWidth + (Cursor.Position.X - _MouseLocation.X);
break;
case 6:
this.Height = this._SelfHeight + (Cursor.Position.Y - _MouseLocation.Y);
Width = Height;//remove if Width<> Height
break;
case 7:
this.Height = this._SelfHeight + (Cursor.Position.Y - _MouseLocation.Y);
this.Width = this._SelfWidth - (Cursor.Position.X - _MouseLocation.X);
this.Location = new Point(Cursor.Position.X - _MouseLocation.X + _SelfLocation.X, _SelfLocation.Y);
break;
case 8:
this.Width = this._SelfWidth - (Cursor.Position.X - _MouseLocation.X);
Height = Width;//remove if Width<> Height
this.Location = new Point(Cursor.Position.X - _MouseLocation.X + _SelfLocation.X, _SelfLocation.Y);
break;
}
}
private void Selection_Move(object sender, EventArgs e)
{
Invalidate();
}
private void ShapeEx_MouseLeave(object sender, EventArgs e)
{
this.Cursor = Cursors.Default;
this._SelectSelctedIndex = -1;
Invalidate();
}
private void ShapeEx_MouseUp(object sender, MouseEventArgs e)
{
this.Cursor = Cursors.Default;
this._SelectSelctedIndex = -1;
Invalidate();
}
}
}