Torna al Thread
public class IconControl : Control
{
//L'icona che sta venendo raffigurata
YourIcon backIcon;
public YourIcon BackedIcon
{
get { return backIcon; }
set
{
if (value != backIcon)
{
backIcon = value;
//Simula un cambiamento di dimensioni per indurre il controllo ad aggiornarsi
this.OnSizeChanged(EventArgs.Empty);
}
}
}
//Il punto da cui deve iniziare il disegno
PointF startPos;
//La dimensione del quadrato esterno
float squareSize;
//La dimensione di ogni pixel dell'immagine
float pixelSize;
//L'ultima casella visitata dall'azione del mouse
Point lastPoint = new Point(-1, -1);
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
//Quando cambia dimensione, ottiene le nuove coordinate di inizio e dimensioni
if (Width < Height)
{
this.squareSize = ClientSize.Width - 1;
startPos.X = 0;
startPos.Y = (ClientSize.Height - squareSize) / 2;
}
else
{
this.squareSize = ClientSize.Height - 1;
startPos.X = (ClientSize.Width - squareSize) / 2;
startPos.Y = 0;
}
if (backIcon == null)
return;
this.pixelSize = squareSize / backIcon.Size;
//Aggiorna l'immagine
using (Graphics g = this.CreateGraphics())
{
this.DrawMe(g);
}
}
private void DrawMe(Graphics graph)
{
if (backIcon == null || squareSize <= 0)
return;
//Per evitare lo sfarfallio, disegna prima su una Bitmap, e
//quindi disegna la bitmap sul controllo
Bitmap bmp = new Bitmap(ClientSize.Width, ClientSize.Height);
//Ottiene il graphics per l'immagine
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
using (Pen pen = new Pen(Color.Black))
{
//Disegna tutte le righe orizzontali e verticali
for (int i = 0; i <= backIcon.Size; i++)
{
float pos = i * pixelSize;
//Riga orizzontale
g.DrawLine(pen, startPos.X, startPos.Y + pos, startPos.X + squareSize, startPos.Y + pos);
//Riga verticale
g.DrawLine(pen, startPos.X + pos, startPos.Y, startPos.X + pos, startPos.Y + squareSize);
}
}
using (Brush b = new SolidBrush(Color.Black))
{
//Cicla fra tutti i bit dell'icona, e colora di nero quelli neri
for (int x = 0; x < backIcon.Size; x++)
{
for (int y = 0; y < backIcon.Size; y++)
{
//Se è nero colora il quadrato
if (backIcon[x, y])
{
g.FillRectangle(b, startPos.X + x * pixelSize,
startPos.Y + y * pixelSize, pixelSize, pixelSize);
}
}
}
}
}
//Disegna l'immagine sul controllo, centrandola
graph.DrawImage(bmp, 0, 0);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
this.DrawMe(pe.Graphics);
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
//Se si sta facendo click, inverte lo stato della casella
if (e.Button == MouseButtons.Left)
{
//Ottiene la casella visitata dal mouse
Point pt = new Point((int)((e.X - startPos.X) / pixelSize),
(int)((e.Y - startPos.Y) / pixelSize));
//Se la casella è la stessa non ripete l'azione, o se è fuori indice
if (pt == lastPoint ||
pt.X >= backIcon.Size || pt.Y >= backIcon.Size ||
pt.X < 0 || pt.Y < 0)
return;
//Altrimenti inverte lo stato e ridisegna, quindi imposta l'ultima casella visitata
this.backIcon[pt.X, pt.Y] = !backIcon[pt.X, pt.Y];
using (Graphics g = this.CreateGraphics())
{
this.DrawMe(g);
}
this.lastPoint = pt;
}
}
}
/// <summary>
/// Gestisce un'icona
/// </summary>
public class YourIcon
{
/// <summary>
/// Ad ogni bit in posizione [x,y] nella matrice, corrsiponde 1 se è nero, 0 se è bianco
/// </summary>
BitArray[] points;
int size;
/// <summary>
/// Costruttore della classe YourIcon
/// </summary>
/// <param name="size">Indica la dimensione dell'icona (size x size)</param>
public YourIcon(int size)
{
this.size = size;
//Crea i punti, inizialmente tutti bianchi
points = new BitArray[size];
for (int i = 0; i < size; i++)
{
points[i] = new BitArray(size, false);
}
}
//Permette di accedere al punto in posizione [x,y]
public bool this[int x, int y]
{
get { return points[x][y]; }
set { points[x][y] = value; }
}
//Consente di ottenere la dimensione dell'Icona
public int Size
{
get
{ return size; }
}
//Salva l'icona su un file
public void Save(Stream stream)
{
byte[] data = Encoding.Default.GetBytes(this.ToString());
stream.Write(data, 0, data.Length);
}
//Converte l'icona in una stringa
public override string ToString()
{
StringBuilder sb = new StringBuilder(size * (size + 2));
//Aggiunge uno 0 per ogni bianco e un 1 per ogni nero
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
sb.Append(points[i][j] ? "0" : "1");
}
sb.AppendLine();
}
//Rimuove gli ultimi due terminatori di riga
sb.Remove(size * (size + 2) - 2, 2);
return sb.ToString();
}
}