/// file: ColorPicker.cs /// Author: Maxime Rohmer /// Brief: Class that is controlling the color usage /// Version: 0.1.0 /// Date: 06/08/2022 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_2 { public partial class ColorPicker : Form { public Color SelectedColor; public Point cursorLocation; public PaintForm main; public ColorPicker(PaintForm theMainForm) { InitializeComponent(); main = theMainForm; } private void ColorPicker_Load(object sender, EventArgs e) { SelectedColor = main.Project.GetCurrentToolColor(main.SelectedLayers); RefreshUi(); } private Bitmap RefreshMap(Size size) { Bitmap map = new Bitmap(size.Width, size.Height); Graphics gr = Graphics.FromImage(map); for (int g = 0; g < size.Width; g += 1) { for (int b = 0; b < size.Height; b += 1) { map.SetPixel(g, b, Color.FromArgb(SelectedColor.A, SelectedColor.R, g, b)); } } int cursorWidth = 15; gr.DrawEllipse(new Pen(Color.Black, 2), new Rectangle(new Point(SelectedColor.G - cursorWidth / 2, SelectedColor.B - cursorWidth / 2), new Size(cursorWidth, cursorWidth))); gr.FillEllipse(new SolidBrush(SelectedColor), new Rectangle(new Point(SelectedColor.G - cursorWidth / 2, SelectedColor.B - cursorWidth / 2), new Size(cursorWidth, cursorWidth))); return map; } private Bitmap RefreshRedLevel(Size size, bool vertical) { Bitmap map = new Bitmap(size.Width, size.Height); Graphics gr = Graphics.FromImage(map); for (int x = 0; x < size.Width; x += 1) { for (int y = 0; y < size.Height; y += 1) { if (vertical) { map.SetPixel(x, y, Color.FromArgb(SelectedColor.A, y, SelectedColor.G, SelectedColor.B)); } else { map.SetPixel(x, y, Color.FromArgb(SelectedColor.A, x, SelectedColor.G, SelectedColor.B)); } } } Rectangle rect; if (vertical) { rect = new Rectangle(0, SelectedColor.R, size.Width / 20, size.Height); } else { rect = new Rectangle(SelectedColor.R, 0, size.Width / 20, size.Height); } gr.FillRectangle(new SolidBrush(Color.FromArgb(214, 214, 214)), rect); gr.DrawRectangle(new Pen(Color.FromArgb(31, 31, 31)), rect); return map; } private Bitmap RefreshGammaLevel(Size size, bool vertical) { Bitmap map = new Bitmap(size.Width, size.Height); Graphics gr = Graphics.FromImage(map); for (int x = 0; x < size.Width; x++) { for (int y = 0; y < size.Height; y++) { if (vertical) { map.SetPixel(x, y, Color.FromArgb(y, y, y, y)); } else { map.SetPixel(x, y, Color.FromArgb(x, x, x, x)); } } } Rectangle rect; if (vertical) { rect = new Rectangle(0, SelectedColor.A, size.Width, size.Height / 20); } else { rect = new Rectangle(SelectedColor.A, 0, size.Width / 20, size.Height); } gr.FillRectangle(new SolidBrush(Color.FromArgb(214, 214, 214)), rect); gr.DrawRectangle(new Pen(Color.FromArgb(31, 31, 31)), rect); return map; } private Bitmap RefreshSelectedColorMap(Size size) { Bitmap bmp = new Bitmap(size.Width, size.Height); Graphics gr = Graphics.FromImage(bmp); gr.FillRectangle(new SolidBrush(SelectedColor), new Rectangle(0, 0, size.Width, size.Height)); return bmp; } private void RefreshUi() { Color Scol = Color.FromArgb(SelectedColor.A, SelectedColor.R, SelectedColor.G, SelectedColor.B); pbxColor.Image = RefreshMap(pbxColor.Size); pbxSliderRed.Image = RefreshRedLevel(pbxSliderRed.Size, false); pbxSliderSaturation.Image = RefreshGammaLevel(pbxSliderSaturation.Size, true); pbxSelectedColor.Image = RefreshSelectedColorMap(pbxSelectedColor.Size); nupRed.Value = Scol.R; nupGreen.Value = Scol.G; nupBlue.Value = Scol.B; nupGamma.Value = Scol.A; tbxColorHex.Text = ColorToHex(Scol); } private void tbrRedLevel_Scroll(object sender, EventArgs e) { RefreshUi(); } private void pbxColor_Click(object sender, EventArgs e) { cursorLocation = pbxColor.PointToClient(MousePosition); if (cursorLocation.X >= 0 && cursorLocation.X < 255 && cursorLocation.Y >= 0 && cursorLocation.Y < 255) { Color newColor = (pbxColor.Image as Bitmap).GetPixel(cursorLocation.X, cursorLocation.Y); if (newColor.R > 0 || newColor.R == 0 && SelectedColor.R < 5) //This is a bad way of fixing a bug where sometimes the mouse inputs are 0,0,0 { SelectedColor = newColor; } RefreshUi(); } } private void pbxSliderRed_Click(object sender, EventArgs e) { int mouseX = pbxSliderRed.PointToClient(MousePosition).X; if (mouseX >= 0 && mouseX < 255) { SelectedColor = Color.FromArgb(SelectedColor.A, mouseX, SelectedColor.G, SelectedColor.B); } RefreshUi(); } private void pbxSliderSaturation_Click(object sender, EventArgs e) { int mouseY = pbxSliderSaturation.PointToClient(MousePosition).Y; if (mouseY >= 0 && mouseY <= 255) { SelectedColor = Color.FromArgb(mouseY, SelectedColor.R, SelectedColor.G, SelectedColor.B); } RefreshUi(); } public static Color HexToColor(string rgb) { int toBase = 16; string raw = rgb; string cleaned = raw.Replace("#", String.Empty); Color result; if (cleaned.Length == 6) { try { int r = Convert.ToInt32(String.Concat(cleaned[0], cleaned[1]), toBase); int g = Convert.ToInt32(String.Concat(cleaned[2], cleaned[3]), toBase); int b = Convert.ToInt32(String.Concat(cleaned[4], cleaned[5]), toBase); result = Color.FromArgb(r, g, b); } catch (Exception e) { Console.WriteLine(e); result = default; } } else { result = default; } return result; } public static string ColorToHex(Color color) { int toBase = 16; string result = "#"; if (color.R < toBase) { result += "0"; } result += Convert.ToString(color.R, toBase); if (color.G < toBase) { result += "0"; } result += Convert.ToString(color.G, toBase); if (color.B < toBase) { result += "0"; } result += Convert.ToString(color.B, toBase); return result; } private void nupValueChanged(object sender, EventArgs e) { int tmpR = (int)nupRed.Value; int tmpG = (int)nupGreen.Value; int tmpB = (int)nupBlue.Value; int tmpA = (int)nupGamma.Value; if (tmpR >= 0 && tmpR <= 255 && tmpG >= 0 && tmpG <= 255 && tmpB >= 0 && tmpB <= 255 && tmpA >= 0 && tmpA <= 255) { Color newColor = Color.FromArgb(tmpA, tmpR, tmpG, tmpB); if (SelectedColor != newColor) { SelectedColor = newColor; RefreshUi(); } } } private void tbxColorHex_TextChanged(object sender, EventArgs e) { Color tmp = HexToColor(tbxColorHex.Text); if (tmp != null) { if (SelectedColor != tmp) { SelectedColor = tmp; } } } private void ColorPicker_FormClosing(object sender, FormClosingEventArgs e) { main.Project.ChangeColor(main.SelectedLayers, SelectedColor); } private void tbxColorHex_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { RefreshUi(); } } private void ColorPicker_Shown(object sender, EventArgs e) { RefreshUi(); } private void pbxSelectedColor_Click(object sender, EventArgs e) { main.Project.ChangeColor(main.SelectedLayers, SelectedColor); } private void tmrRefresh_Tick(object sender, EventArgs e) { pbxSliderSaturation_Click(sender, e); pbxSliderRed_Click(sender, e); } private void tmrRefreshMain_Tick(object sender, EventArgs e) { pbxColor_Click(sender, e); } private void SliderMouseDown(object sender, MouseEventArgs e) { tmrRefreshBars.Enabled = true; } private void SliderMouseUp(object sender, MouseEventArgs e) { tmrRefreshBars.Enabled = false; } private void pbxColor_MouseDown(object sender, MouseEventArgs e) { tmrRefreshMain.Enabled = true; } private void pbxColor_MouseUp(object sender, MouseEventArgs e) { tmrRefreshMain.Enabled = false; } } }