using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Drawing.Drawing2D; using System.Linq; using System.Reflection; using System.Text; using System.Windows.Forms; using HeuristicLab.Core.Views; using HeuristicLab.MainForm; namespace HeuristicLab.Analysis.FitnessLandscape.BoxChart { [View("ColorValue View")] [Content(typeof(ColorValue), IsDefaultView = true)] public sealed partial class ColorValueView : NamedItemView { private Bitmap colorWheel; private const int RADIUS = 128; private const int COLOR_COUNT = 128; public new ColorValue Content { get { return (ColorValue)base.Content; } set { base.Content = value; } } public ColorValueView() { InitializeComponent(); InitializeColorWheel(); } protected override void DeregisterContentEvents() { Content.ColorChanged -= Content_ColorChanged; base.DeregisterContentEvents(); } protected override void RegisterContentEvents() { base.RegisterContentEvents(); Content.ColorChanged += Content_ColorChanged; } #region Event Handlers (Content) private void Content_ColorChanged(object sender, EventArgs e) { if (InvokeRequired) { Invoke(new EventHandler(Content_ColorChanged), sender, e); } else { UpdateControls(); colorWheelPanel.Invalidate(); colorPanel.Invalidate(); brightnessPanel.Invalidate(); } } #endregion protected override void OnContentChanged() { base.OnContentChanged(); Update(() => { UpdateControls(); colorWheelPanel.Invalidate(); colorPanel.Invalidate(); brightnessPanel.Invalidate(); }); } private void UpdateControls() { if (Content == null) { hueScrollBar.Value = 0; saturationScrollBar.Value = 0; brightnessScrollBar.Value = 0; hueUpDown.Value = 0; saturationUpDown.Value = 0; brightnessUpDown.Value = 0; redScrollBar.Value = 0; greenScrollBar.Value = 0; blueScrollBar.Value = 0; redUpDown.Value = 0; greenUpDown.Value = 0; blueUpDown.Value = 0; } else { hueScrollBar.Value = (int)Math.Round(Content.H); saturationScrollBar.Value = (int)Math.Round(Content.S*100); brightnessScrollBar.Value = (int)Math.Round(Content.V*100); hueUpDown.Value = (decimal)Math.Round(Content.H); saturationUpDown.Value = (decimal)Math.Round(Content.S*100); brightnessUpDown.Value = (decimal)Math.Round(Content.V*100); redScrollBar.Value = Content.R; greenScrollBar.Value = Content.G; blueScrollBar.Value = Content.B; redUpDown.Value = Content.R; greenUpDown.Value = Content.G; blueUpDown.Value = Content.B; } } protected override void SetEnabledStateOfControls() { base.SetEnabledStateOfControls(); hueScrollBar.Enabled = saturationScrollBar.Enabled = brightnessScrollBar.Enabled = redScrollBar.Enabled = greenScrollBar.Enabled = blueScrollBar.Enabled = hueUpDown.Enabled = saturationUpDown.Enabled = brightnessUpDown.Enabled = redUpDown.Enabled = greenUpDown.Enabled = blueUpDown.Enabled = Content != null; } private static Color GetFullColor(ColorValue c) { return new ColorValue(c.H, c.S, 1).Color; } private static Point GetColorPoint(ColorValue c, int size) { return GetPoint(c.H, c.S*size/2, new Point(size/2, size/2)); } #region Event Handlers (child controls) private void colorWheelPanel_Paint(object sender, PaintEventArgs e) { e.Graphics.DrawImage(colorWheel, 0, 0, colorWheelPanel.Width, colorWheelPanel.Height); if (Content != null) DrawColorPointer(e.Graphics, GetColorPoint(Content, Math.Min(colorWheelPanel.Width, colorWheelPanel.Height))); } private void brightnessPanel_Paint(object sender, PaintEventArgs e) { if (Content != null) { var bar = brightnessPanel.ClientRectangle; bar.Width -= 10; using (var lgb = new LinearGradientBrush(bar, GetFullColor(Content), Color.Black, LinearGradientMode.Vertical)) { e.Graphics.FillRectangle(lgb, bar); } DrawBrighnessPointer(e.Graphics, new Point(bar.Width-9, (int)Math.Round((1.0-Content.V)*bar.Height))); } } private void colorPanel_Paint(object sender, PaintEventArgs e) { if (Content != null) { using (var b = new SolidBrush(Content.Color)) { e.Graphics.FillRectangle(b, 0, 0, colorPanel.Width, colorPanel.Height); } } } private bool updateInProgress = false; private void Update(Action thunk) { if (!updateInProgress) { updateInProgress = true; thunk(); updateInProgress = false; } } private void hueScrollBar_ValueChanged(object sender, EventArgs e) { Update(() => Content.H = hueScrollBar.Value); } private void saturationScrollBar_ValueChanged(object sender, EventArgs e) { Update(() => Content.S = saturationScrollBar.Value/100.0); } private void brightnessScrollBar_ValueChanged(object sender, EventArgs e) { Update(() => Content.V = brightnessScrollBar.Value/100.0); } private void redScrollBar_ValueChanged(object sender, EventArgs e) { Update(() => Content.R = redScrollBar.Value); } private void greenScrollBar_ValueChanged(object sender, EventArgs e) { Update(() => Content.G = greenScrollBar.Value); } private void blueScrollBar_ValueChanged(object sender, EventArgs e) { Update(() => Content.B = blueScrollBar.Value); } private void hueUpDown_ValueChanged(object sender, EventArgs e) { Update(() => Content.H = (double)hueUpDown.Value); } private void saturationUpDown_ValueChanged(object sender, EventArgs e) { Update(() => Content.S = (double)saturationUpDown.Value/100.0); } private void brightnessUpDown_ValueChanged(object sender, EventArgs e) { Update(() => Content.V = (double)brightnessUpDown.Value/100.0); } private void redUpDown_ValueChanged(object sender, EventArgs e) { Update(() => Content.R = (int)redUpDown.Value); } private void greenUpDown_ValueChanged(object sender, EventArgs e) { Update(() => Content.G = (int)greenUpDown.Value); } private void blueUpDown_ValueChanged(object sender, EventArgs e) { Update(() => Content.B = (int)blueUpDown.Value); } private void colorWheelPanel_MouseDown(object sender, MouseEventArgs e) { Update(() => SetColorWheel(e.Location)); } private void colorWheelPanel_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) Update(() => SetColorWheel(e.Location)); } private void brightnessPanel_MouseDown(object sender, MouseEventArgs e) { Update(() => SetBrightness(e.Location)); } private void brightnessPanel_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { Update(() => SetBrightness(e.Location)); } } private void colorPanel_DoubleClick(object sender, EventArgs e) { colorDialog.Color = Content.Color; if (colorDialog.ShowDialog() == DialogResult.OK) { Update(() => Content.Color = colorDialog.Color); } } private void defaultColorPanel_MouseClick(object sender, MouseEventArgs e) { if (Content != null) Update(() => Content.Color = ((Panel)sender).BackColor); } #endregion #region Auxiliary Functions private void DrawColorPointer(Graphics g, Point p) { g.DrawRectangle(Pens.Black, p.X - 3, p.Y - 3, 6, 6); } private void DrawBrighnessPointer(Graphics g, Point p) { g.FillPolygon(Brushes.Black, new[] { p, new Point(p.X + 10, p.Y + 5), new Point(p.X + 10, p.Y - 5)}); } private void InitializeColorWheel() { colorWheel = new Bitmap(256, 256); using (var brush = new PathGradientBrush(GetPoints(RADIUS, new Point(RADIUS, RADIUS))) { CenterColor = Color.White, CenterPoint = new PointF(RADIUS, RADIUS), SurroundColors = GetColors() }) { using (var g = Graphics.FromImage(colorWheel)) { g.FillEllipse(brush, 0, 0, colorWheelPanel.Width, colorWheel.Height); } } SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.DoubleBuffer, true); } private static Point[] GetPoints(double radius, Point center) { var points = new Point[COLOR_COUNT]; for (int i = 0; i