diff --git a/Cyotek.Windows.Forms.ColorPicker/ColorPickerUserControl.Designer.cs b/Cyotek.Windows.Forms.ColorPicker/ColorPickerUserControl.Designer.cs new file mode 100644 index 0000000..7aee9bb --- /dev/null +++ b/Cyotek.Windows.Forms.ColorPicker/ColorPickerUserControl.Designer.cs @@ -0,0 +1,179 @@ +using System; + +namespace Cyotek.Windows.Forms +{ + partial class ColorPickerUserControl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.okButton = new System.Windows.Forms.Button(); + this.cancelButton = new System.Windows.Forms.Button(); + this.previewPanel = new System.Windows.Forms.Panel(); + this.loadPaletteButton = new System.Windows.Forms.Button(); + this.savePaletteButton = new System.Windows.Forms.Button(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.screenColorPicker = new Cyotek.Windows.Forms.ScreenColorPicker(); + this.colorWheel = new Cyotek.Windows.Forms.ColorWheel(); + this.colorEditor = new Cyotek.Windows.Forms.ColorEditor(); + this.colorGrid = new Cyotek.Windows.Forms.ColorGrid(); + this.colorEditorManager = new Cyotek.Windows.Forms.ColorEditorManager(); + this.SuspendLayout(); + // + // okButton + // + this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.okButton.Location = new System.Drawing.Point(453, 12); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(75, 23); + this.okButton.TabIndex = 1; + this.okButton.Text = "OK"; + this.okButton.UseVisualStyleBackColor = true; + this.okButton.Click += new System.EventHandler(this.okButton_Click); + // + // cancelButton + // + this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(453, 41); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 2; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); + // + // previewPanel + // + this.previewPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.previewPanel.Location = new System.Drawing.Point(453, 203); + this.previewPanel.Name = "previewPanel"; + this.previewPanel.Size = new System.Drawing.Size(75, 47); + this.previewPanel.TabIndex = 3; + this.previewPanel.Paint += new System.Windows.Forms.PaintEventHandler(this.previewPanel_Paint); + // + // loadPaletteButton + // + this.loadPaletteButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.loadPaletteButton.Image = global::Cyotek.Windows.Forms.Properties.Resources.LoadPalette; + this.loadPaletteButton.Location = new System.Drawing.Point(12, 147); + this.loadPaletteButton.Name = "loadPaletteButton"; + this.loadPaletteButton.Size = new System.Drawing.Size(23, 23); + this.loadPaletteButton.TabIndex = 5; + this.toolTip.SetToolTip(this.loadPaletteButton, "Load Palette"); + this.loadPaletteButton.UseVisualStyleBackColor = false; + this.loadPaletteButton.Click += new System.EventHandler(this.loadPaletteButton_Click); + // + // savePaletteButton + // + this.savePaletteButton.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.savePaletteButton.Image = global::Cyotek.Windows.Forms.Properties.Resources.SavePalette; + this.savePaletteButton.Location = new System.Drawing.Point(34, 147); + this.savePaletteButton.Name = "savePaletteButton"; + this.savePaletteButton.Size = new System.Drawing.Size(23, 23); + this.savePaletteButton.TabIndex = 6; + this.toolTip.SetToolTip(this.savePaletteButton, "Save Palette"); + this.savePaletteButton.UseVisualStyleBackColor = false; + this.savePaletteButton.Click += new System.EventHandler(this.savePaletteButton_Click); + // + // screenColorPicker + // + this.screenColorPicker.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.screenColorPicker.Color = System.Drawing.Color.Black; + this.screenColorPicker.Image = global::Cyotek.Windows.Forms.Properties.Resources.eyedropper; + this.screenColorPicker.Location = new System.Drawing.Point(453, 83); + this.screenColorPicker.Name = "screenColorPicker"; + this.screenColorPicker.Size = new System.Drawing.Size(73, 85); + this.toolTip.SetToolTip(this.screenColorPicker, "Click and drag to select screen color"); + this.screenColorPicker.Zoom = 6; + // + // colorWheel + // + this.colorWheel.Color = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.colorWheel.Location = new System.Drawing.Point(12, 12); + this.colorWheel.Name = "colorWheel"; + this.colorWheel.Size = new System.Drawing.Size(192, 147); + this.colorWheel.TabIndex = 4; + // + // colorEditor + // + this.colorEditor.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.colorEditor.Color = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.colorEditor.Location = new System.Drawing.Point(210, 12); + this.colorEditor.Name = "colorEditor"; + this.colorEditor.Size = new System.Drawing.Size(230, 238); + this.colorEditor.TabIndex = 0; + // + // colorGrid + // + this.colorGrid.AutoAddColors = false; + this.colorGrid.CellBorderStyle = Cyotek.Windows.Forms.ColorCellBorderStyle.None; + this.colorGrid.EditMode = Cyotek.Windows.Forms.ColorEditingMode.Both; + this.colorGrid.Location = new System.Drawing.Point(12, 176); + this.colorGrid.Name = "colorGrid"; + this.colorGrid.Padding = new System.Windows.Forms.Padding(0); + this.colorGrid.Palette = Cyotek.Windows.Forms.ColorPalette.Paint; + this.colorGrid.SelectedCellStyle = Cyotek.Windows.Forms.ColorGridSelectedCellStyle.Standard; + this.colorGrid.ShowCustomColors = false; + this.colorGrid.Size = new System.Drawing.Size(192, 72); + this.colorGrid.Spacing = new System.Drawing.Size(0, 0); + this.colorGrid.TabIndex = 7; + this.colorGrid.EditingColor += new System.EventHandler(this.colorGrid_EditingColor); + // + // colorEditorManager + // + this.colorEditorManager.ColorEditor = this.colorEditor; + this.colorEditorManager.ColorGrid = this.colorGrid; + this.colorEditorManager.ColorWheel = this.colorWheel; + this.colorEditorManager.ScreenColorPicker = this.screenColorPicker; + this.colorEditorManager.ColorChanged += new System.EventHandler(this.colorEditorManager_ColorChanged); + // + // ColorPickerDialog + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(540, 262); + this.Controls.Add(this.savePaletteButton); + this.Controls.Add(this.loadPaletteButton); + this.Controls.Add(this.previewPanel); + this.Controls.Add(this.cancelButton); + this.Controls.Add(this.okButton); + this.Controls.Add(this.screenColorPicker); + this.Controls.Add(this.colorWheel); + this.Controls.Add(this.colorEditor); + this.Controls.Add(this.colorGrid); + this.Name = "ColorPickerDialog"; + this.Text = "Color Picker"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ColorGrid colorGrid; + private ColorEditor colorEditor; + private ColorWheel colorWheel; + private ColorEditorManager colorEditorManager; + private ScreenColorPicker screenColorPicker; + private System.Windows.Forms.Button okButton; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Panel previewPanel; + private System.Windows.Forms.Button loadPaletteButton; + private System.Windows.Forms.Button savePaletteButton; + private System.Windows.Forms.ToolTip toolTip; + } +} \ No newline at end of file diff --git a/Cyotek.Windows.Forms.ColorPicker/ColorPickerUserControl.cs b/Cyotek.Windows.Forms.ColorPicker/ColorPickerUserControl.cs new file mode 100644 index 0000000..768df9f --- /dev/null +++ b/Cyotek.Windows.Forms.ColorPicker/ColorPickerUserControl.cs @@ -0,0 +1,295 @@ +using Cyotek.Windows.Forms; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.IO; +using System.Linq; +using System.Windows.Forms; + +namespace Cyotek.Windows.Forms +{ + // Cyotek Color Picker controls library + // Copyright © 2013-2017 Cyotek Ltd. + // http://cyotek.com/blog/tag/colorpicker + + // Licensed under the MIT License. See license.txt for the full text. + + // If you use this code in your applications, donations or attribution are welcome + + [DefaultEvent("PreviewColorChanged")] + [DefaultProperty("Color")] + public partial class ColorPickerUserControl : UserControl + { + #region Constants + + private static readonly object _eventPreviewColorChanged = new object(); + + #endregion + + #region Fields + + private Brush _textureBrush; + + #endregion + + #region Constructors + + public ColorPickerUserControl() + { + this.ShowAlphaChannel = true; + this.Font = SystemFonts.DialogFont; + } + + #endregion + + #region Events + + [Category("Property Changed")] + public event EventHandler PreviewColorChanged + { + add { this.Events.AddHandler(_eventPreviewColorChanged, value); } + remove { this.Events.RemoveHandler(_eventPreviewColorChanged, value); } + } + + #endregion + + #region Properties + + public Color Color + { + get { return colorEditorManager.Color; } + set { colorEditorManager.Color = value; } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool ShowAlphaChannel { get; set; } + + #endregion + + #region Methods + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_textureBrush != null) + { + _textureBrush.Dispose(); + _textureBrush = null; + } + } + + base.Dispose(disposing); + } + + /// + /// Raises the event. + /// + /// An that contains the event data. + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + colorEditor.ShowAlphaChannel = this.ShowAlphaChannel; + + if (!this.ShowAlphaChannel) + { + for (int i = 0; i < colorGrid.Colors.Count; i++) + { + Color color; + + color = colorGrid.Colors[i]; + if (color.A != 255) + { + colorGrid.Colors[i] = Color.FromArgb(255, color); + } + } + } + } + + /// + /// Raises the event. + /// + /// The instance containing the event data. + protected virtual void OnPreviewColorChanged(EventArgs e) + { + EventHandler handler; + + handler = (EventHandler)this.Events[_eventPreviewColorChanged]; + + handler?.Invoke(this, e); + } + + private void cancelButton_Click(object sender, EventArgs e) + { + //this.DialogResult = DialogResult.Cancel; + //this.Close(); + } + + private void colorEditorManager_ColorChanged(object sender, EventArgs e) + { + previewPanel.Invalidate(); + + this.OnPreviewColorChanged(e); + } + + private void colorGrid_EditingColor(object sender, EditColorCancelEventArgs e) + { + e.Cancel = true; + + using (ColorDialog dialog = new ColorDialog + { + FullOpen = true, + Color = e.Color + }) + { + if (dialog.ShowDialog(this) == DialogResult.OK) + { + colorGrid.Colors[e.ColorIndex] = dialog.Color; + } + } + } + + private void loadPaletteButton_Click(object sender, EventArgs e) + { + using (FileDialog dialog = new OpenFileDialog + { + Filter = PaletteSerializer.DefaultOpenFilter, + DefaultExt = "pal", + Title = "Open Palette File" + }) + { + if (dialog.ShowDialog(this) == DialogResult.OK) + { + try + { + IPaletteSerializer serializer; + + serializer = PaletteSerializer.GetSerializer(dialog.FileName); + if (serializer != null) + { + ColorCollection palette; + + if (!serializer.CanRead) + { + throw new InvalidOperationException("Serializer does not support reading palettes."); + } + + using (FileStream file = File.OpenRead(dialog.FileName)) + { + palette = serializer.Deserialize(file); + } + + if (palette != null) + { + // we can only display 96 colors in the color grid due to it's size, so if there's more, bin them + while (palette.Count > 96) + { + palette.RemoveAt(palette.Count - 1); + } + + // or if we have less, fill in the blanks + while (palette.Count < 96) + { + palette.Add(Color.White); + } + + colorGrid.Colors = palette; + } + } + else + { + MessageBox.Show("Sorry, unable to open palette, the file format is not supported or is not recognized.", "Load Palette", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + catch (Exception ex) + { + MessageBox.Show(string.Format("Sorry, unable to open palette. {0}", ex.GetBaseException().Message), "Load Palette", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } + + private void okButton_Click(object sender, EventArgs e) + { + //this.DialogResult = DialogResult.OK; + //this.Close(); + } + + private void previewPanel_Paint(object sender, PaintEventArgs e) + { + Rectangle region; + + region = previewPanel.ClientRectangle; + + if (this.Color.A != 255) + { + if (_textureBrush == null) + { + using (Bitmap background = new Bitmap(this.GetType().Assembly.GetManifestResourceStream(string.Concat(this.GetType().Namespace, ".Resources.cellbackground.png")))) + { + _textureBrush = new TextureBrush(background, WrapMode.Tile); + } + } + + e.Graphics.FillRectangle(_textureBrush, region); + } + + using (Brush brush = new SolidBrush(this.Color)) + { + e.Graphics.FillRectangle(brush, region); + } + + e.Graphics.DrawRectangle(SystemPens.ControlText, region.Left, region.Top, region.Width - 1, region.Height - 1); + } + + private void savePaletteButton_Click(object sender, EventArgs e) + { + using (FileDialog dialog = new SaveFileDialog + { + Filter = PaletteSerializer.DefaultSaveFilter, + DefaultExt = "pal", + Title = "Save Palette File As" + }) + { + if (dialog.ShowDialog(this) == DialogResult.OK) + { + IPaletteSerializer serializer; + + serializer = PaletteSerializer.AllSerializers.Where(s => s.CanWrite).ElementAt(dialog.FilterIndex - 1); + if (serializer != null) + { + if (!serializer.CanWrite) + { + throw new InvalidOperationException("Serializer does not support writing palettes."); + } + + try + { + using (FileStream file = File.OpenWrite(dialog.FileName)) + { + serializer.Serialize(file, colorGrid.Colors); + } + } + catch (Exception ex) + { + MessageBox.Show(string.Format("Sorry, unable to save palette. {0}", ex.GetBaseException().Message), "Save Palette", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + else + { + MessageBox.Show("Sorry, unable to save palette, the file format is not supported or is not recognized.", "Save Palette", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + } + } + + #endregion + } +} diff --git a/Cyotek.Windows.Forms.ColorPicker/ColorPickerUserControl.resx b/Cyotek.Windows.Forms.ColorPicker/ColorPickerUserControl.resx new file mode 100644 index 0000000..0f309c8 --- /dev/null +++ b/Cyotek.Windows.Forms.ColorPicker/ColorPickerUserControl.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 177, 17 + + + 17, 17 + + \ No newline at end of file diff --git a/Cyotek.Windows.Forms.ColorPicker/Cyotek.Windows.Forms.ColorPicker.csproj b/Cyotek.Windows.Forms.ColorPicker/Cyotek.Windows.Forms.ColorPicker.csproj index a766d81..f37f871 100644 --- a/Cyotek.Windows.Forms.ColorPicker/Cyotek.Windows.Forms.ColorPicker.csproj +++ b/Cyotek.Windows.Forms.ColorPicker/Cyotek.Windows.Forms.ColorPicker.csproj @@ -53,6 +53,12 @@ + + UserControl + + + ColorPickerUserControl.cs + Form @@ -129,6 +135,10 @@ + + ColorPickerUserControl.cs + Designer + ResXFileCodeGenerator Resources.Designer.cs