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(); } } }