/* Made by Lonami Exo
* (C) LonamiWebs
* Made the 20-02-2015 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
public class PixelBox : PictureBox
{
public bool PaintMode;
bool _ShowGrid;
public bool ShowGrid {
get { return _ShowGrid; }
set {
_ShowGrid = value;
Invalidate();
}
}
public int CanvasSize {
get { return Pixels.Size; }
set { Pixels.Size = value; }
}
PixelMap Pixels = new PixelMap();
public Color CurrentColor = Color.Black;
public PixelBox()
{
Pixels.Size = CanvasSize;
MouseDown += PixelBox_MouseDown;
MouseMove += PixelBox_MouseMove;
SizeChanged += (sender, e) => Size = new Size(Size.Width, Size.Width);
Pixels.PixelsChanged += Invalidate;
}
protected override void OnPaint(PaintEventArgs pe)
{
log("on paint");
var g = pe.Graphics;
g.Clear(BackColor);
double s = (double)Width / (double)Pixels.Size; // Size of the pixel in the PixelBox
var pixels = Pixels.GetPixels();
foreach (var pixel in Pixels.GetPixels())
g.FillRectangle(new SolidBrush(pixel.PixelColor), GetRectangleF(pixel.Location.X, pixel.Location.Y, s));
if (ShowGrid)
{
var pen = new Pen(ForeColor);
for (double x = 0; x <= Width; x += s)
g.DrawLine(pen, (float)x, 0, (float)x, Width);
for (double y = 0; y <= Width; y += s)
g.DrawLine(pen, 0, (float)y, Width, (float)y);
}
base.OnPaint(pe);
log("done paint");
}
RectangleF GetRectangleF(int pixelX, int pixelY, double s)
{
double x = (double)(pixelX - 1) * s; // I don't know exactly why, this needs to be lowered by 1
double y = (double)pixelY * s;
float vx = (float)x;
float vy = Width - (float)y; // Y axis needs to be inverted
return new RectangleF(vx, vy, (float)s, (float)s);
}
void PixelBox_MouseDown(object sender, MouseEventArgs e)
{
if (!PaintMode)
return;
Pixels.SetPixel(GetPoint(e.Location), CurrentColor);
}
void PixelBox_MouseMove(object sender, MouseEventArgs e)
{
if (!PaintMode || e.Button != MouseButtons.Left)
return;
Pixels.SetPixel(GetPoint(e.Location), CurrentColor);
}
Point GetPoint(Point location)
{
int mx = location.X; // The current location
int my = Height - location.Y; // Y axis needs to be inverted
int vx, vy; // Valid X and Y
vx = vy = 0;
double s = (double)Width / (double)Pixels.Size; // Size of the pixel in the PixelBox
for (double x = 0; x <= Width; x += s)
for (double y = 0; y <= Width; y += s)
if (mx > x - s && mx < x && my > y - s && my < y)
{
vx = (int)(x / s);
vy = (int)(y / s);
break;
}
return new Point(vx, vy);
}
public static void log(params object[] msgs) {
System.Diagnostics.Debug.WriteLine(String.Join(", ", msgs));
}
}
public class PixelMap
{
#region Delegates and events
public delegate void PixelsChangedDelegate();
public event PixelsChangedDelegate PixelsChanged;
#endregion
#region Variables and properties
public class Pixel
{
public readonly Point Location;
public readonly Color PixelColor;
public Pixel(Point location, Color color)
{
Location = location;
PixelColor = color;
}
}
int _Size = 16;
public int Size
{
get { return _Size; }
set {
_Size = value;
CheckPixels();
}
}
List<Pixel> Pixels = new List<Pixel>();
#endregion
#region Public methods
public void Clear()
{
Pixels.Clear();
TellPixelsChanged();
}
public List<Pixel> GetPixels()
{
return Pixels;
}
public void SetPixel(int x, int y, Color color)
{
SetPixel(new Point(x, y), color);
}
public void SetPixel(Point point, Color color)
{
if (!IsValidPoint(point))
return;
var found = Pixels.Where(p => p.Location.X == point.X && p.Location.Y == point.Y).ToList();
if (found.Count > 0)
Pixels.Remove(found[0]);
Pixels.Add(new Pixel(point, color));
TellPixelsChanged();
}
#endregion
#region Private methods
void CheckPixels()
{
Pixels = Pixels.Where(p => IsValidPoint(p.Location)).ToList();
TellPixelsChanged();
}
void TellPixelsChanged() {
if (PixelsChanged != null)
PixelsChanged();
}
bool IsValidPoint(Point point) { return point.X > 0 && point.X <= Size && point.Y > 0 && point.Y <= Size; }
#endregion
}
PictureBox are just fine but, why not a Pixel Box? With this, you can easily implement a pixel box to your forms project, and even paint on it!
Be the first to comment
You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.