Merge pull request #1466 from schani/stage-unified-card-table-scanning
[mono.git] / mcs / class / System.Drawing.Design / System.Drawing.Design / ColorEditor.cs
index b1dd13e90854a2f7298bac5865b78e82b1445fde..1f1f23ccccc0ee4aae4b72d1f0088dbf6cf406d0 100644 (file)
@@ -2,11 +2,13 @@
 // 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()
                {
@@ -48,34 +55,114 @@ namespace System.Drawing.Design
                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)
@@ -90,10 +177,202 @@ namespace System.Drawing.Design
                        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
                }
        }
 }