// System.Drawing.Design.ColorEditor.cs
//
// Authors:
-// Martin Willemoes Hansen (mwh@sysrq.dk)
-// Andreas Nahr (ClassDevelopment@A-SoftTech.com)
+// Martin Willemoes Hansen (mwh@sysrq.dk)\r
+// Andreas Nahr (ClassDevelopment@A-SoftTech.com)\r
+// Jonathan Chambers (joncham@gmail.com)
//
-// (C) 2003 Martin Willemoes Hansen
-// (C) 2003 Andreas Nahr
+// (C) 2003 Martin Willemoes Hansen\r
+// (C) 2003 Andreas Nahr\r
+// (C) 2006 Jonathan Chambers
//
//
using System;
using System.Drawing;
+using System.Drawing.Design;
using System.ComponentModel;
using System.Windows.Forms;
+using System.Windows.Forms.Design;
namespace System.Drawing.Design
{
public class ColorEditor : UITypeEditor
{
- private ColorDialog colorEdit;
+ private IWindowsFormsEditorService editorService;
+ private Color selected_color;
+ private bool color_chosen;
+ private Control editor_control = null;
public ColorEditor()
{
public override object EditValue (ITypeDescriptorContext context,
IServiceProvider provider, object value)
{
- // TODO MS.Net is using a in place color editor. We just use the modal
- // Windows.Forms.ColorDialog to keep things simple for now
- // especially as Windows.Forms are not fully implemented right now
+ if (context != null && provider != null) {
+ editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
+ if (editorService != null) {
+ if (editor_control == null)
+ editor_control = GetEditorControl (value);
+ editorService.DropDownControl(editor_control);
+ if (color_chosen)
+ return selected_color;
+ else
+ return null;
+ }
+ }
+ return base.EditValue(context, provider, value);
+ }
+
+ private Control GetEditorControl (object value)
+ {
+ TabControl tab_control = new TabControl();
+ tab_control.Dock = DockStyle.Fill;
+ TabPage custom_tab = new TabPage("Custom");
+ TabPage web_tab = new TabPage("Web");
+ TabPage system_tab = new TabPage("System");
+
+ ColorListBox web_listbox = new ColorListBox();
+ ColorListBox system_listbox = new ColorListBox();
+ web_listbox.Dock = DockStyle.Fill;
+ system_listbox.Dock = DockStyle.Fill;
- colorEdit = new ColorDialog ();
+ web_tab.Controls.Add(web_listbox);
+ system_tab.Controls.Add(system_listbox);
+
+ SystemColorCompare system_compare = new SystemColorCompare();
+ System.Collections.ArrayList color_list = new System.Collections.ArrayList();
+ foreach (System.Reflection.PropertyInfo property in typeof(SystemColors).GetProperties(System.Reflection.BindingFlags.Public |System.Reflection.BindingFlags.Static)) {
+ Color clr = (Color)property.GetValue(null,null);
+ color_list.Add(clr);
+ }
+ color_list.Sort(system_compare);
+ system_listbox.Items.AddRange(color_list.ToArray());
+ system_listbox.MouseUp+=new MouseEventHandler(HandleMouseUp);
+ system_listbox.SelectedValueChanged+=new EventHandler(HandleChange);
+
+ WebColorCompare web_compare = new WebColorCompare();
+ color_list = new System.Collections.ArrayList();
+ foreach (KnownColor known_color in Enum.GetValues(typeof(KnownColor)))
+ {
+ Color color = Color.FromKnownColor(known_color);
+ if (color.IsSystemColor)
+ continue;
+ color_list.Add(color);
+ }
+ color_list.Sort(web_compare);
+ web_listbox.Items.AddRange(color_list.ToArray());
+ web_listbox.MouseUp+=new MouseEventHandler(HandleMouseUp);
+ web_listbox.SelectedValueChanged+=new EventHandler(HandleChange);\r
- if (value is Color)
- colorEdit.Color = (Color) value;
- else
- // Set default
- colorEdit.Color = Color.White; // TODO set which color as default?
+ CustomColorPicker custom_picker = new CustomColorPicker ();\r
+ custom_picker.Dock = DockStyle.Fill;\r
+ custom_picker.ColorChanged += new EventHandler (CustomColorPicked);\r
+ custom_tab.Controls.Add (custom_picker);
- colorEdit.FullOpen = true;
- DialogResult result = colorEdit.ShowDialog();
+ tab_control.TabPages.Add(custom_tab);
+ tab_control.TabPages.Add(web_tab);
+ tab_control.TabPages.Add(system_tab);
- if (result == DialogResult.OK)
- return colorEdit.Color;
- else
- return value;
+ if (value != null) {
+ Color current_color = (Color)value;
+ if (current_color.IsSystemColor)
+ {
+ system_listbox.SelectedValue = current_color;
+ tab_control.SelectedTab = system_tab;
+ }
+ else if (current_color.IsKnownColor)
+ {
+ web_listbox.SelectedValue = current_color;
+ tab_control.SelectedTab = web_tab;
+ }
+ selected_color = current_color;
+ color_chosen = true;
+ }
+
+ tab_control.Height = 216; // the height of the custom colors tab
+ return tab_control;
}
- public override UITypeEditorEditStyle GetEditStyle (ITypeDescriptorContext context)
+ private void HandleChange(object sender, EventArgs e)
{
- return UITypeEditorEditStyle.Modal;
+ selected_color = (Color)((ColorListBox)sender).Items[((ColorListBox)sender).SelectedIndex];
+ color_chosen = true;
+ }
- // TODO UITypeEditorEditStyle.DropDown is returned by the MS.Net library
- // see EditValue why we use a modal window for now
- // return UITypeEditorEditStyle.DropDown;
+ private void CustomColorPicked (object sender, EventArgs e)\r
+ {
+ selected_color = (Color)sender;
+ color_chosen = true;
+ if (editorService != null)
+ editorService.CloseDropDown ();\r
+ }
+
+ private void HandleMouseUp(object sender, MouseEventArgs e)
+ {
+ if (editorService != null)
+ editorService.CloseDropDown();
+ }
+
+ public override UITypeEditorEditStyle GetEditStyle (ITypeDescriptorContext context)
+ {
+ return UITypeEditorEditStyle.DropDown;
}
public override bool GetPaintValueSupported (ITypeDescriptorContext context)
if (e.Value != null)
{
Color C = (Color) e.Value;
- G.FillRectangle (new SolidBrush (C), e.Bounds);
+ using (SolidBrush sb = new SolidBrush (C))
+ G.FillRectangle (sb, e.Bounds);
+ }
+ }
+
+ class ColorListBox : ListBox {
+ public ColorListBox() {
+ this.DrawMode = DrawMode.OwnerDrawFixed;
+ this.Sorted = true;
+ this.ItemHeight = 14;
+ this.BorderStyle = BorderStyle.FixedSingle;
+ }
+
+ protected override void OnDrawItem(DrawItemEventArgs e) {
+ e.DrawBackground();
+ Color color = (Color)this.Items[e.Index];
+ using (System.Drawing.SolidBrush brush = new SolidBrush(color))
+ e.Graphics.FillRectangle(brush, 2,e.Bounds.Top+2,21,9);
+ e.Graphics.DrawRectangle(SystemPens.WindowText, 2,e.Bounds.Top+2,21,9);
+ e.Graphics.DrawString(color.Name, this.Font, SystemBrushes.WindowText, 26,e.Bounds.Top);
+ if ((e.State & DrawItemState.Selected) != 0)
+ e.DrawFocusRectangle();
+ base.OnDrawItem (e);
+ }
+ }
+
+ class SystemColorCompare : System.Collections.IComparer {
+ #region IComparer Members
+
+ public int Compare(object x, object y) {
+ Color c1 = (Color)x;
+ Color c2 = (Color)y;
+ return String.Compare(c1.Name, c2.Name);
+ }
+
+ #endregion
+ }
+ class WebColorCompare : System.Collections.IComparer
+ {
+ #region IComparer Members
+
+ public int Compare(object x, object y)
+ {
+ Color c1 = (Color)x;
+ Color c2 = (Color)y;
+ return String.Compare(c1.Name, c2.Name);
}
- G.DrawRectangle (Pens.Black, e.Bounds);
+ #endregion
+ }\r
+\r
+\r
+ class CustomColorPicker : UserControl\r
+ {\r
+ Color[,] colors;\r
+ bool highlighting;\r
+ int x, y;\r
+ public CustomColorPicker ()\r
+ {\r
+ colors = new Color[8, 8];\r
+ colors[0, 0] = Color.White;\r
+ colors[1, 0] = Color.FromArgb (224, 224, 224);\r
+ colors[2, 0] = Color.Silver;\r
+ colors[3, 0] = Color.Gray;\r
+ colors[4, 0] = Color.FromArgb (64, 64, 64);\r
+ colors[5, 0] = Color.Black;\r
+ colors[6, 0] = Color.White;\r
+ colors[7, 0] = Color.White;\r
+\r
+ colors[0, 1] = Color.FromArgb (255, 192, 192);\r
+ colors[1, 1] = Color.FromArgb (255, 128, 128);\r
+ colors[2, 1] = Color.Red;\r
+ colors[3, 1] = Color.FromArgb (192, 0, 0);\r
+ colors[4, 1] = Color.Maroon;\r
+ colors[5, 1] = Color.FromArgb (64, 0, 0);\r
+ colors[6, 1] = Color.White;\r
+ colors[7, 1] = Color.White;\r
+\r
+ colors[0, 2] = Color.FromArgb (255, 224, 192);\r
+ colors[1, 2] = Color.FromArgb (255, 192, 128);\r
+ colors[2, 2] = Color.FromArgb (255, 128, 0);\r
+ colors[3, 2] = Color.FromArgb (192, 64, 0);\r
+ colors[4, 2] = Color.FromArgb (128, 64, 0);\r
+ colors[5, 2] = Color.FromArgb (128, 64, 64);\r
+ colors[6, 2] = Color.White;\r
+ colors[7, 2] = Color.White;\r
+\r
+ colors[0, 3] = Color.FromArgb (255, 255, 192);\r
+ colors[1, 3] = Color.FromArgb (255, 255, 128);\r
+ colors[2, 3] = Color.Yellow;\r
+ colors[3, 3] = Color.FromArgb (192, 192, 0);\r
+ colors[4, 3] = Color.Olive;\r
+ colors[5, 3] = Color.FromArgb (64, 64, 0);\r
+ colors[6, 3] = Color.White;\r
+ colors[7, 3] = Color.White;\r
+\r
+ colors[0, 4] = Color.FromArgb (192, 255, 192);\r
+ colors[1, 4] = Color.FromArgb (128, 255, 128);\r
+ colors[2, 4] = Color.Lime;\r
+ colors[3, 4] = Color.FromArgb (0, 192, 0);\r
+ colors[4, 4] = Color.Green;\r
+ colors[5, 4] = Color.FromArgb (0, 64, 0);\r
+ colors[6, 4] = Color.White;\r
+ colors[7, 4] = Color.White;\r
+\r
+ colors[0, 5] = Color.FromArgb (192, 255, 255);\r
+ colors[1, 5] = Color.FromArgb (128, 255, 255);\r
+ colors[2, 5] = Color.Cyan;\r
+ colors[3, 5] = Color.FromArgb (0, 192, 192);\r
+ colors[4, 5] = Color.Teal;\r
+ colors[5, 5] = Color.FromArgb (0, 64, 64);\r
+ colors[6, 5] = Color.White;\r
+ colors[7, 5] = Color.White;\r
+\r
+ colors[0, 6] = Color.FromArgb (192, 192, 255);\r
+ colors[1, 6] = Color.FromArgb (128, 128, 255);\r
+ colors[2, 6] = Color.Blue;\r
+ colors[3, 6] = Color.FromArgb (0, 0, 192);\r
+ colors[4, 6] = Color.Navy;\r
+ colors[5, 6] = Color.FromArgb (0, 0, 64);\r
+ colors[6, 6] = Color.White;\r
+ colors[7, 6] = Color.White;\r
+\r
+ colors[0, 7] = Color.FromArgb (255, 192, 255);\r
+ colors[1, 7] = Color.FromArgb (255, 128, 255);\r
+ colors[2, 7] = Color.Fuchsia;\r
+ colors[3, 7] = Color.FromArgb (192, 0, 192);\r
+ colors[4, 7] = Color.Purple;\r
+ colors[5, 7] = Color.FromArgb (64, 0, 64);\r
+ colors[6, 7] = Color.White;\r
+ colors[7, 7] = Color.White;\r
+ }\r
+\r
+ public event EventHandler ColorChanged;\r
+\r
+ protected override void OnPaint (PaintEventArgs e)\r
+ {\r
+ for (int i = 0; i < 8; i++)\r
+ for (int j = 0; j < 8; j++) {\r
+ DrawRect (e.Graphics, colors[i, j], j * 24, i * 24);\r
+ }\r
+\r
+ if (highlighting) {\r
+ int i = x / 24;\r
+ int j = y / 24;\r
+ ControlPaint.DrawFocusRectangle (e.Graphics, new Rectangle (i * 24 - 2, j * 24 - 2, 24, 24));\r
+ }\r
+\r
+ base.OnPaint (e);\r
+ }\r
+\r
+ void DrawRect (Graphics g, Color color, int x, int y)\r
+ {\r
+ using (SolidBrush brush = new SolidBrush (color))\r
+ g.FillRectangle (brush, x, y, 20, 20);\r
+ ControlPaint.DrawBorder3D (g, x, y, 20, 20);\r
+ }\r
+\r
+ protected override void OnMouseDown (MouseEventArgs e)\r
+ {\r
+ if (e.X % 24 < 20 && e.Y % 24 < 20) {\r
+ x = e.X;\r
+ y = e.Y;\r
+ highlighting = true;\r
+ Invalidate ();\r
+ }\r
+ base.OnMouseDown (e);\r
+ }\r
+\r
+ protected override void OnMouseUp (MouseEventArgs e)\r
+ {\r
+ if (highlighting && this.ClientRectangle.Contains (e.X, e.Y)) {\r
+ if (ColorChanged != null)\r
+ ColorChanged (colors[y / 24, x / 24], EventArgs.Empty);\r
+ highlighting = false;\r
+ }\r
+ base.OnMouseUp (e);\r
+ }\r
+\r
+ protected override void OnMouseMove (MouseEventArgs e)\r
+ {\r
+ if (highlighting) {\r
+ int old_x = x;\r
+ int old_y = y;\r
+ x = e.X;\r
+ y = e.Y;\r
+ if ((old_x / 24 != x / 24 || old_y / 24 != y / 24) &&\r
+ x / 24 < 8 && y / 24 < 8) {\r
+ Region r = new Region ();\r
+ r.Union (new Rectangle (old_x - 2, old_y - 2, 24, 24));\r
+ r.Union (new Rectangle (x - 2, y - 2, 24, 24));\r
+ Invalidate (r);\r
+ }\r
+ }\r
+ base.OnMouseMove (e);\r
+ }\r
}
}
}