private void BitmapSelector_MouseDown(object sender, MouseEventArgs e)
{
Point p = Translate(e.Location);
if (e.Button == MouseButtons.Left)
mouse1Down = true;
else if (e.Button == MouseButtons.Right)
mouse2Down = true;
toolTip.Hide(this);
if (cursorVisible)
{
Cursor.Hide();
cursorVisible = false;
}
if (customBrush != null)
{
OnCustomBrushClick(new CustomBrushClickEventArgs(p.X - (customBrush.Width >> 1), p.Y - (customBrush.Height >> 1)));
customBrush.Dispose();
customBrush = null;
RedrawBrushLayer(p);
Redraw();
}
else if (Brush == BrushType.Rectangle)
{
mouseDownLast = p;
}
else if (Brush == BrushType.Fill)
{
//http://en.wikipedia.org/wiki/Flood_fill#Alternative_implementations
Bitmap b = Layers[SelectionLayerIndex].Image;
Rectangle bounds = new Rectangle(0, 0, b.Width, b.Height);
Queue<Point> q = new Queue<Point>();
Color c = mouse1Down ? SelectionColor : Color.Transparent;
q.Enqueue(p);
while (q.Count > 0)
{
Point curr = q.Dequeue();
if (!SelectionBounds.IsEmpty && !SelectionBounds.Contains(curr))
continue;
if (!bounds.Contains(curr))
continue;
//since every pixel is either red or transparent, only compairng alpha
//will work, and avoid an issue with 00000000 != 00ffffff even though
//both are invisible
if (b.GetPixel(curr.X, curr.Y).A != c.A)
{
b.SetPixel(curr.X, curr.Y, c);
q.Enqueue(new Point(curr.X - 1, curr.Y));
q.Enqueue(new Point(curr.X + 1, curr.Y));
q.Enqueue(new Point(curr.X, curr.Y - 1));
q.Enqueue(new Point(curr.X, curr.Y + 1));
}
}
}
else if (BrushDiameter > 1)
{
using (Graphics g = Graphics.FromImage(Layers[SelectionLayerIndex].Image))
{
if (!SelectionBounds.IsEmpty)
g.SetClip(SelectionBounds);
g.CompositingMode = CompositingMode.SourceCopy;
SolidBrush b = new SolidBrush(mouse1Down ? SelectionColor : Color.Transparent);
if (Brush == BrushType.Round)
g.FillEllipse(b, p.X - BrushDiameter / 2, p.Y - BrushDiameter / 2, BrushDiameter, BrushDiameter);
else
g.FillRectangle(b, p.X - BrushDiameter / 2, p.Y - BrushDiameter / 2, BrushDiameter, BrushDiameter);
b.Dispose();
}
}
else if (p.X >= 0 && p.X < Width && p.Y >= 0 && p.Y < Height && (SelectionBounds.IsEmpty || SelectionBounds.Contains(p)))
Layers[SelectionLayerIndex].Image.SetPixel(p.X, p.Y, mouse1Down ? SelectionColor : Color.Transparent);
Redraw();
}