Paint

Тема в разделе ".NET - WinForms", создана пользователем ilya00, 21 май 2015.

  1. ilya00

    ilya00 Member

    Регистрация:
    13 янв 2013
    Сообщения:
    23
    Симпатии:
    0
    продолжаю мучить Paint =)) короче щас я так резко продвинулся уже, в общем посмотрите код, проблема в том что все инструменты получаются одного цвета :( что то перемудрил с лямбдами... и еще никак не соображу как мне сделать выделение области (как в паинте), с одной стороны мне кажется это вообще должен быть еще один UserControl, с другой стороны хочется все наследовать от ToolBase...

    Код (Text):
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
     
     
     
     
    public class PaintBox : UserControl
    {
        public enum PaintTools : int { Curve, Line, Figure, Eraser };
     
     
     
     
        public class PaintProperties
        {
            public Color Color = Color.Black;
     
     
     
     
            public int Transparency = 255;
     
     
     
     
            public int Size = 10;
     
     
     
     
            public readonly ReadOnlyCollection<Func<Bitmap>> DefaultTextures;
     
     
     
     
            public Func<Bitmap> Texture;
     
     
     
     
            public Brush Brush
            {
                get
                {
                    return new TextureBrush(Texture());
                }
            }
     
     
     
     
            public Pen Pen
            {
                get
                {
                    return new Pen(Brush, Size);
                }
            }
     
     
     
     
            public Rectangle GetPaintRect(Point center, int padding = 0)
            {
                int x = center.X - Size - padding;
                int y = center.Y - Size - padding;
                int width = (Size + padding) * 2 + 1;
                int height = (Size + padding) * 2 + 1;
                return new Rectangle(x, y, width, height);
            }
     
     
     
     
            public PaintProperties()
            {
                var dt = new List<Func<Bitmap>>();
     
     
     
     
                dt.Add(() =>
                {
                    var bmp = new Bitmap(100, 100);
                    var gr = Graphics.FromImage(bmp);
                    gr.FillRectangle(new SolidBrush(Color), 0, 0, bmp.Width, bmp.Height);
                    return bmp;
                });
     
     
     
     
                dt.Add(() =>
                {
                    var bmp = new Bitmap(100, 100);
                    var gr = Graphics.FromImage(bmp);
                    var pen = new Pen(Color);
                    for (int i = 0; i < bmp.Height; i += 10)
                        gr.DrawLine(pen, 0, i, bmp.Width, i);
                    return bmp;
                });
     
     
     
     
                dt.Add(() =>
                {
                    var bmp = new Bitmap(100, 100);
                    var gr = Graphics.FromImage(bmp);
                    var pen = new Pen(Color);
                    for (int i = 0; i <= bmp.Width; i += 10)
                        gr.DrawLine(pen, i, 0, i, bmp.Height);
                    return bmp;
                });
     
     
     
     
                DefaultTextures = new ReadOnlyCollection<Func<Bitmap>>(dt);
                Texture = DefaultTextures[0];
            }
     
     
     
     
            public PaintProperties(PaintProperties prop) : this()
            {
                Color = prop.Color;
                Transparency = prop.Transparency;
                Size = prop.Size;
                Texture = prop.Texture;
            }
        }
     
     
     
     
        private abstract class ToolBase
        {
            public PaintProperties Properties = new PaintProperties();
     
     
     
     
            protected List<Point> Points = new List<Point>();
     
     
     
     
            public abstract void Draw(Graphics graphics);
     
     
     
     
            public virtual void Add(Point point)
            {
                Points.Add(point);
            }
     
     
     
     
            public virtual void Clear()
            {
                Points.Clear();
            }
        }
     
     
     
     
        private class Curve : ToolBase
        {
            public override void Draw(Graphics graphics)
            {
                if (Points.Count > 1)
                    graphics.DrawLines(Properties.Pen, Points.ToArray());
     
     
     
     
                if (Points.Count == 1)
                    graphics.FillEllipse(Properties.Brush, Properties.GetPaintRect(Points[0]));
            }
        }
     
     
     
     
        private class Line : ToolBase
        {
            public override void Draw(Graphics graphics)
            {
                if (Points.Count > 1)
                    graphics.DrawLine(Properties.Pen, Points[0], Points[1]);
            }
     
     
     
     
            public override void Add(Point point)
            {
                if (Points.Count < 2)
                    Points.Add(point);
                else
                    Points[0] = point;
            }
        }
     
     
     
     
        public PaintProperties Properties = new PaintProperties();
        public PaintTools CurrentTool = PaintTools.Curve;
        private ToolBase Tool;
        private Bitmap Buffer;
        private List<ToolBase> History = new List<ToolBase>();
        private const int MaxHystoryLength = 100;
        private List<ToolBase> HistoryReceive = new List<ToolBase>();
     
     
     
     
        public PaintBox()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                     ControlStyles.OptimizedDoubleBuffer |
                     ControlStyles.UserPaint,
                     true);
        }
     
     
     
     
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Buffer = new Bitmap(ClientSize.Width, ClientSize.Height);
            var graphics = Graphics.FromImage(Buffer);
            graphics.FillRectangle(Brushes.White, 0, 0, Buffer.Width, Buffer.Height);
        }
     
     
     
     
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            e.Graphics.DrawImageUnscaled(Buffer, Point.Empty);
        }
     
     
     
     
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
     
     
     
     
            foreach (var tool in History)
                tool.Draw(e.Graphics);
     
     
     
     
            if (Tool != null)
                Tool.Draw(e.Graphics);
        }
     
     
     
     
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (e.Button == MouseButtons.Left)
            {
                Tool.Add(e.Location);
                Invalidate(Tool.Properties.GetPaintRect(e.Location, 5));
            }
        }
     
     
     
     
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (e.Button == MouseButtons.Left)
            {
                switch (CurrentTool)
                {
                    case PaintTools.Curve: Tool = new Curve(); break;
                    case PaintTools.Line: Tool = new Line(); break;
                    default: Tool = null; break;
                }
                Tool.Properties = new PaintProperties(Properties);
            }
        }
     
     
     
     
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
     
     
     
     
            if (Tool != null)
            {
                History.Add(Tool);
                HistoryReceive.Clear();
            }
     
     
     
     
            Tool = null;
     
     
     
     
            if (History.Count > MaxHystoryLength)
            {
                Rasterize(new[] { History[0] }, Buffer);
                History.RemoveAt(0);
            }
     
     
     
     
            Invalidate();
        }
     
     
     
     
        private void Rasterize(IEnumerable<ToolBase> tools, Bitmap bitmap)
        {
            var graphics = Graphics.FromImage(bitmap);
            foreach (var tool in tools)
                tool.Draw(graphics);
        }
     
     
     
     
        public Bitmap Image
        {
            get
            {
                var result = new Bitmap(Buffer);
                var graphics = Graphics.FromImage(result);
                graphics.DrawImageUnscaled(Buffer, Point.Empty);
                Rasterize(History, result);
                return result;
            }
            set
            {
                Buffer = new Bitmap(value);
            }
        }
     
     
     
     
        public bool CanCancel
        {
            get
            {
                return History.Count > 0;
            }
        }
     
     
     
     
        public bool CanReceive
        {
            get
            {
                return HistoryReceive.Count > 0;
            }
        }
     
     
     
     
        public void Cancel()
        {
            if (CanCancel)
            {
                HistoryReceive.Add(History[History.Count - 1]);
                History.RemoveAt(History.Count - 1);
                Invalidate();
            }
        }
     
     
     
     
        public void Receive()
        {
            if (CanReceive)
            {
                History.Add(HistoryReceive[HistoryReceive.Count - 1]);
                HistoryReceive.RemoveAt(HistoryReceive.Count - 1);
                Invalidate();
            }
        }
    }
    Код (Text):
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
     
     
     
     
    namespace Paint
    {
        public partial class Form1 : Form
        {
            PaintBox pb = new PaintBox { Left = 100, Top = 100, Width = 600, Height = 600 };
            SaveFileDialog sfdlg = new SaveFileDialog() { Filter = "Image|*.png;*.bmp;*.jpg", DefaultExt = ".png" };
            ColorDialog cdlg = new ColorDialog();
     
     
     
     
            public Form1()
            {
                InitializeComponent();
     
     
     
     
                pb.Parent = this;
     
     
     
     
                var btn = new Button { Parent = this, Text = "Color" };
                btn.Click += SelectColor;
     
     
     
     
                int index = 1;
                btn = new Button { Parent = this, Text = "Fill", Left = 100 };
                btn.Click += delegate { pb.Properties.Texture =
                    pb.Properties.DefaultTextures[index++ % pb.Properties.DefaultTextures.Count]; };
     
     
     
     
                btn = new Button { Parent = this, Text = "Size", Left = 200 };
                btn.Click += delegate { pb.Properties.Size = (pb.Properties.Size + 2) % 11; };
     
     
     
     
                btn = new Button { Parent = this, Text = "Transparency", Left = 300 };
                btn.Click += delegate { pb.Properties.Transparency = (pb.Properties.Transparency + 40) % 255; };
     
     
     
     
                btn = new Button { Parent = this, Text = "Type", Left = 400 };
                btn.Click += delegate { pb.CurrentTool = (PaintBox.PaintTools)((int)(pb.CurrentTool + 1) % 2); };
     
     
     
     
                btn = new Button { Parent = this, Text = "Cancel", Left = 500 };
                btn.Click += delegate { pb.Cancel(); };
     
     
     
     
                btn = new Button { Parent = this, Text = "Receive", Left = 600 };
                btn.Click += delegate { pb.Receive(); };
     
     
     
     
                btn = new Button { Parent = this, Text = "Save", Left = 700 };
                btn.Click += SaveDialog;
     
     
     
     
                Size = new Size(800, 800);
            }
     
     
     
     
            private void SaveDialog(object sender, EventArgs e)
            {
                if (sfdlg.ShowDialog() == DialogResult.OK)
                    pb.Image.Save(sfdlg.FileName);
            }
     
     
     
     
            private void SelectColor(object sender, EventArgs e)
            {
                if (cdlg.ShowDialog() == DialogResult.OK)
                    pb.Properties.Color = cdlg.Color;
            }
        }
    }
     
    з.ы. в редакторе кодов есть все языки кроме шарпа -_- странно)))
     
  2. ilya00

    ilya00 Member

    Регистрация:
    13 янв 2013
    Сообщения:
    23
    Симпатии:
    0
    короче с изменением цветов разобрался, оказывается я то присваивал функцию от объекта, она продолжала на него ссылаться и цвет менялся соответственно, щас сделал весь этот список статическим и норм... остается вопрос с выделением и пожалуй надо сделать какие то стандартные фигуры (прямоугольник, треугольник, эллипс...) тоже чет пока никак не соображу
     
Загрузка...

Поделиться этой страницей