From 252435208abb20a7a2ab62e64a48c5d321542764 Mon Sep 17 00:00:00 2001 From: dexy Date: Fri, 12 Jul 2024 09:14:56 +1000 Subject: [PATCH] PR #85 but ported ColourPicker from CodeX instead --- CodeWalker.Core/Utils/Utils.cs | 9 + CodeWalker.Core/Utils/Vectors.cs | 32 + CodeWalker/App.config | 89 +- .../Project/Panels/EditYmapGrassPanel.cs | 5 +- CodeWalker/Properties/Settings.Designer.cs | 256 +++--- CodeWalker/Properties/Settings.settings | 65 +- CodeWalker/Utils/ColourPicker.Designer.cs | 339 +++++++ CodeWalker/Utils/ColourPicker.cs | 866 ++++++++++++++++++ CodeWalker/Utils/ColourPicker.resx | 123 +++ CodeWalker/Utils/ColourPickerForm.Designer.cs | 92 ++ CodeWalker/Utils/ColourPickerForm.cs | 54 ++ CodeWalker/Utils/ColourPickerForm.resx | 409 +++++++++ CodeWalker/WorldForm.Designer.cs | 49 +- CodeWalker/WorldForm.cs | 5 + 14 files changed, 2190 insertions(+), 203 deletions(-) create mode 100644 CodeWalker/Utils/ColourPicker.Designer.cs create mode 100644 CodeWalker/Utils/ColourPicker.cs create mode 100644 CodeWalker/Utils/ColourPicker.resx create mode 100644 CodeWalker/Utils/ColourPickerForm.Designer.cs create mode 100644 CodeWalker/Utils/ColourPickerForm.cs create mode 100644 CodeWalker/Utils/ColourPickerForm.resx diff --git a/CodeWalker.Core/Utils/Utils.cs b/CodeWalker.Core/Utils/Utils.cs index f29415f..3d69eb0 100644 --- a/CodeWalker.Core/Utils/Utils.cs +++ b/CodeWalker.Core/Utils/Utils.cs @@ -261,6 +261,15 @@ namespace CodeWalker } + public static float Saturate(float f) + { + return (f > 1.0f) ? 1.0f : (f < 0.0f) ? 0.0f : f; + } + public static float Clamp(float f, float min, float max) + { + return f > max ? max : f < min ? min : f; + } + } diff --git a/CodeWalker.Core/Utils/Vectors.cs b/CodeWalker.Core/Utils/Vectors.cs index 301ee4e..191a3ac 100644 --- a/CodeWalker.Core/Utils/Vectors.cs +++ b/CodeWalker.Core/Utils/Vectors.cs @@ -339,6 +339,38 @@ namespace CodeWalker return Vector3.Cross(rd, p - ro).Length(); } + + public static float DistanceFieldTest(in Vector2 s, in Vector2 p1, in Vector2 p2, out int winding) + { + //utility function to help in calculating distance field textures. + //finds the distance from a sample point to a line segment, + //outputting a winding value for use to determine if the sample point is inside or outside a shape. + var d = PointSegmentDistance(s, p1, p2); + winding = 0; + var d1 = p1 - s; + var d2 = p2 - s; + if ((d1.Y > 0) != (d2.Y > 0))//this segment crosses the y-axis (relative to s) + { + var yr = (0 - d1.Y) / (d2.Y - d1.Y);//how far along the line is the intersection? + var xr = d1.X + (d2.X - d1.X) * yr;//where on the x axis is the intersection? + if (xr > 0) + { + winding = (d2.Y > d1.Y) ? 1 : -1; + } + } + return d; + } + public static float PointSegmentDistance(in Vector2 v, in Vector2 a, in Vector2 b) + { + var ab = b - a; + var av = v - a; + var l2 = ab.LengthSquared(); + if (l2 == 0) return av.Length(); + var t = FloatUtil.Saturate(Vector2.Dot(av, ab) / l2); + var p = a + t * ab; + return (p - v).Length(); + } + } diff --git a/CodeWalker/App.config b/CodeWalker/App.config index 38524be..de87735 100644 --- a/CodeWalker/App.config +++ b/CodeWalker/App.config @@ -43,27 +43,6 @@ True - - 720 - - - True - - - Global - - - contrails - - - True - - - True - - - True - True @@ -172,27 +151,6 @@ - - - - Move Forwards: W - Move Backwards: S - Move Left: A - Move Right: D - Move Up: R - Move Down: F - Move Slower / Zoom In: Z - Move Faster / Zoom Out: X - Toggle Mouse Select: C - Toggle Toolbar: T - Exit Edit Mode: Q - Edit Position: W - Edit Rotation: E - Edit Scale: R - - - True @@ -247,6 +205,53 @@ + + 720 + + + True + + + Global + + + contrails + + + EXTRASUNNY + + + True + + + True + + + + + Move Forwards: W + Move Backwards: S + Move Left: A + Move Right: D + Move Up: R + Move Down: F + Move Slower / Zoom In: Z + Move Faster / Zoom Out: X + Toggle Mouse Select: C + Toggle Toolbar: T + Exit Edit Mode: Q + Edit Position: W + Edit Rotation: E + Edit Scale: R + + + + + + + + + diff --git a/CodeWalker/Project/Panels/EditYmapGrassPanel.cs b/CodeWalker/Project/Panels/EditYmapGrassPanel.cs index fd5a5f8..e8298a3 100644 --- a/CodeWalker/Project/Panels/EditYmapGrassPanel.cs +++ b/CodeWalker/Project/Panels/EditYmapGrassPanel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Windows.Forms; using CodeWalker.GameFiles; +using CodeWalker.Utils; using CodeWalker.World; using SharpDX; @@ -106,9 +107,9 @@ namespace CodeWalker.Project.Panels private void GrassColorLabel_Click(object sender, EventArgs e) { - var colDiag = new ColorDialog {Color = GrassColorLabel.BackColor}; + var colDiag = new ColourPickerForm { SelectedColour = GrassColorLabel.BackColor }; if (colDiag.ShowDialog(this) == DialogResult.OK) - GrassColorLabel.BackColor = colDiag.Color; + GrassColorLabel.BackColor = colDiag.SelectedColour; } private void BrushModeCheckBox_CheckedChanged(object sender, EventArgs e) diff --git a/CodeWalker/Properties/Settings.Designer.cs b/CodeWalker/Properties/Settings.Designer.cs index 0f96979..9602c01 100644 --- a/CodeWalker/Properties/Settings.Designer.cs +++ b/CodeWalker/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace CodeWalker.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")] public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -142,7 +142,7 @@ namespace CodeWalker.Properties { this["Wireframe"] = value; } } - + [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] @@ -154,43 +154,7 @@ namespace CodeWalker.Properties { this["Skydome"] = value; } } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("True")] - public bool LODLights { - get { - return ((bool)(this["LODLights"])); - } - set { - this["LODLights"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("True")] - public bool NatrualAmbientLight { - get { - return ((bool)(this["NatrualAmbientLight"])); - } - set { - this["NatrualAmbientLight"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("True")] - public bool ArtificialAmbientLight { - get { - return ((bool)(this["ArtificialAmbientLight"])); - } - set { - this["ArtificialAmbientLight"] = value; - } - } - + [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] @@ -526,55 +490,7 @@ namespace CodeWalker.Properties { this["RenderMode"] = value; } } - - [global::System.Configuration.UserScopedSetting()] - [global::System.Diagnostics.DebuggerNonUserCode()] - [global::System.Configuration.DefaultSettingValue("EXTRASUNNY")] - public string Weather { - get { - return ((string)(this["Weather"])); - } - set { - this["Weather"] = value; - } - } - - [global::System.Configuration.UserScopedSetting()] - [global::System.Diagnostics.DebuggerNonUserCode()] - [global::System.Configuration.DefaultSettingValue("GLOBAL")] - public string Region { - get { - return ((string)(this["Region"])); - } - set { - this["Region"] = value; - } - } - - [global::System.Configuration.UserScopedSetting()] - [global::System.Diagnostics.DebuggerNonUserCode()] - [global::System.Configuration.DefaultSettingValue("contrails")] - public string Clouds { - get { - return ((string)(this["Clouds"])); - } - set { - this["Clouds"] = value; - } - } - - [global::System.Configuration.UserScopedSetting()] - [global::System.Diagnostics.DebuggerNonUserCode()] - [global::System.Configuration.DefaultSettingValue("720")] - public int TimeOfDay { - get { - return ((int)(this["TimeOfDay"])); - } - set { - this["TimeOfDay"] = value; - } - } - + [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("DiffuseSampler")] @@ -671,34 +587,6 @@ namespace CodeWalker.Properties { } } - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - Move Forwards: W - Move Backwards: S - Move Left: A - Move Right: D - Move Up: R - Move Down: F - Move Slower / Zoom In: Z - Move Faster / Zoom Out: X - Toggle Mouse Select: C - Toggle Toolbar: T - Exit Edit Mode: Q - Edit Position: W - Edit Rotation: E - Edit Scale: R -")] - public global::System.Collections.Specialized.StringCollection KeyBindings { - get { - return ((global::System.Collections.Specialized.StringCollection)(this["KeyBindings"])); - } - set { - this["KeyBindings"] = value; - } - } - [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] @@ -914,5 +802,141 @@ namespace CodeWalker.Properties { this["RPFExplorerStartFolder"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("720")] + public int TimeOfDay { + get { + return ((int)(this["TimeOfDay"])); + } + set { + this["TimeOfDay"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool LODLights { + get { + return ((bool)(this["LODLights"])); + } + set { + this["LODLights"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Global")] + public string Region { + get { + return ((string)(this["Region"])); + } + set { + this["Region"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("contrails")] + public string Clouds { + get { + return ((string)(this["Clouds"])); + } + set { + this["Clouds"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("EXTRASUNNY")] + public string Weather { + get { + return ((string)(this["Weather"])); + } + set { + this["Weather"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool NatrualAmbientLight { + get { + return ((bool)(this["NatrualAmbientLight"])); + } + set { + this["NatrualAmbientLight"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool ArtificialAmbientLight { + get { + return ((bool)(this["ArtificialAmbientLight"])); + } + set { + this["ArtificialAmbientLight"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + Move Forwards: W + Move Backwards: S + Move Left: A + Move Right: D + Move Up: R + Move Down: F + Move Slower / Zoom In: Z + Move Faster / Zoom Out: X + Toggle Mouse Select: C + Toggle Toolbar: T + Exit Edit Mode: Q + Edit Position: W + Edit Rotation: E + Edit Scale: R +")] + public global::System.Collections.Specialized.StringCollection KeyBindings { + get { + return ((global::System.Collections.Specialized.StringCollection)(this["KeyBindings"])); + } + set { + this["KeyBindings"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ColourPickerCustomColours { + get { + return ((string)(this["ColourPickerCustomColours"])); + } + set { + this["ColourPickerCustomColours"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ColourPickerRecentColours { + get { + return ((string)(this["ColourPickerRecentColours"])); + } + set { + this["ColourPickerRecentColours"] = value; + } + } } } diff --git a/CodeWalker/Properties/Settings.settings b/CodeWalker/Properties/Settings.settings index 0164951..312fa92 100644 --- a/CodeWalker/Properties/Settings.settings +++ b/CodeWalker/Properties/Settings.settings @@ -143,25 +143,6 @@ - - <?xml version="1.0" encoding="utf-16"?> -<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> - <string>Move Forwards: W</string> - <string>Move Backwards: S</string> - <string>Move Left: A</string> - <string>Move Right: D</string> - <string>Move Up: R</string> - <string>Move Down: F</string> - <string>Move Slower / Zoom In: Z</string> - <string>Move Faster / Zoom Out: X</string> - <string>Toggle Mouse Select: C</string> - <string>Toggle Toolbar: T</string> - <string>Exit Edit Mode: Q</string> - <string>Edit Position: W</string> - <string>Edit Rotation: E</string> - <string>Edit Scale: R</string> -</ArrayOfString> - True @@ -216,5 +197,51 @@ + + 720 + + + True + + + Global + + + contrails + + + EXTRASUNNY + + + True + + + True + + + <?xml version="1.0" encoding="utf-16"?> +<ArrayOfString xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <string>Move Forwards: W</string> + <string>Move Backwards: S</string> + <string>Move Left: A</string> + <string>Move Right: D</string> + <string>Move Up: R</string> + <string>Move Down: F</string> + <string>Move Slower / Zoom In: Z</string> + <string>Move Faster / Zoom Out: X</string> + <string>Toggle Mouse Select: C</string> + <string>Toggle Toolbar: T</string> + <string>Exit Edit Mode: Q</string> + <string>Edit Position: W</string> + <string>Edit Rotation: E</string> + <string>Edit Scale: R</string> +</ArrayOfString> + + + + + + + \ No newline at end of file diff --git a/CodeWalker/Utils/ColourPicker.Designer.cs b/CodeWalker/Utils/ColourPicker.Designer.cs new file mode 100644 index 0000000..89dd723 --- /dev/null +++ b/CodeWalker/Utils/ColourPicker.Designer.cs @@ -0,0 +1,339 @@ +namespace CodeWalker.Utils +{ + partial class ColourPicker + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component 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.HRadio = new System.Windows.Forms.RadioButton(); + this.HTextBox = new System.Windows.Forms.TextBox(); + this.HLabel = new System.Windows.Forms.Label(); + this.SLabel = new System.Windows.Forms.Label(); + this.STextBox = new System.Windows.Forms.TextBox(); + this.SRadio = new System.Windows.Forms.RadioButton(); + this.VLabel = new System.Windows.Forms.Label(); + this.VTextBox = new System.Windows.Forms.TextBox(); + this.VRadio = new System.Windows.Forms.RadioButton(); + this.RTextBox = new System.Windows.Forms.TextBox(); + this.RRadio = new System.Windows.Forms.RadioButton(); + this.GTextBox = new System.Windows.Forms.TextBox(); + this.GRadio = new System.Windows.Forms.RadioButton(); + this.BTextBox = new System.Windows.Forms.TextBox(); + this.BRadio = new System.Windows.Forms.RadioButton(); + this.HexTextBox = new System.Windows.Forms.TextBox(); + this.HexLabel = new System.Windows.Forms.Label(); + this.ATextBox = new System.Windows.Forms.TextBox(); + this.ARadio = new System.Windows.Forms.RadioButton(); + this.NewLabel = new System.Windows.Forms.Label(); + this.OldLabel = new System.Windows.Forms.Label(); + this.PaletteLabel = new System.Windows.Forms.Label(); + this.UpdateTimer = new System.Windows.Forms.Timer(this.components); + this.SuspendLayout(); + // + // HRadio + // + HRadio.AutoSize = true; + HRadio.Checked = true; + HRadio.Location = new System.Drawing.Point(334, 39); + HRadio.Name = "HRadio"; + HRadio.Size = new System.Drawing.Size(34, 19); + HRadio.TabIndex = 0; + HRadio.TabStop = true; + HRadio.Text = "H"; + HRadio.UseVisualStyleBackColor = true; + HRadio.CheckedChanged += HRadio_CheckedChanged; + // + // HTextBox + // + HTextBox.Location = new System.Drawing.Point(372, 38); + HTextBox.Name = "HTextBox"; + HTextBox.Size = new System.Drawing.Size(35, 23); + HTextBox.TabIndex = 1; + HTextBox.Text = "0"; + HTextBox.TextChanged += HTextBox_TextChanged; + // + // HLabel + // + HLabel.AutoSize = true; + HLabel.Location = new System.Drawing.Point(410, 41); + HLabel.Name = "HLabel"; + HLabel.Size = new System.Drawing.Size(12, 15); + HLabel.TabIndex = 2; + HLabel.Text = "°"; + // + // SLabel + // + SLabel.AutoSize = true; + SLabel.Location = new System.Drawing.Point(410, 70); + SLabel.Name = "SLabel"; + SLabel.Size = new System.Drawing.Size(17, 15); + SLabel.TabIndex = 5; + SLabel.Text = "%"; + // + // STextBox + // + STextBox.Location = new System.Drawing.Point(372, 67); + STextBox.Name = "STextBox"; + STextBox.Size = new System.Drawing.Size(35, 23); + STextBox.TabIndex = 4; + STextBox.Text = "0"; + STextBox.TextChanged += STextBox_TextChanged; + // + // SRadio + // + SRadio.AutoSize = true; + SRadio.Location = new System.Drawing.Point(334, 68); + SRadio.Name = "SRadio"; + SRadio.Size = new System.Drawing.Size(31, 19); + SRadio.TabIndex = 3; + SRadio.Text = "S"; + SRadio.UseVisualStyleBackColor = true; + SRadio.CheckedChanged += SRadio_CheckedChanged; + // + // VLabel + // + VLabel.AutoSize = true; + VLabel.Location = new System.Drawing.Point(410, 99); + VLabel.Name = "VLabel"; + VLabel.Size = new System.Drawing.Size(17, 15); + VLabel.TabIndex = 8; + VLabel.Text = "%"; + // + // VTextBox + // + VTextBox.Location = new System.Drawing.Point(372, 96); + VTextBox.Name = "VTextBox"; + VTextBox.Size = new System.Drawing.Size(35, 23); + VTextBox.TabIndex = 7; + VTextBox.Text = "0"; + VTextBox.TextChanged += VTextBox_TextChanged; + // + // VRadio + // + VRadio.AutoSize = true; + VRadio.Location = new System.Drawing.Point(334, 97); + VRadio.Name = "VRadio"; + VRadio.Size = new System.Drawing.Size(32, 19); + VRadio.TabIndex = 6; + VRadio.Text = "B"; + VRadio.UseVisualStyleBackColor = true; + VRadio.CheckedChanged += VRadio_CheckedChanged; + // + // RTextBox + // + RTextBox.Location = new System.Drawing.Point(372, 129); + RTextBox.Name = "RTextBox"; + RTextBox.Size = new System.Drawing.Size(35, 23); + RTextBox.TabIndex = 10; + RTextBox.Text = "0"; + RTextBox.TextChanged += RTextBox_TextChanged; + // + // RRadio + // + RRadio.AutoSize = true; + RRadio.Location = new System.Drawing.Point(334, 130); + RRadio.Name = "RRadio"; + RRadio.Size = new System.Drawing.Size(32, 19); + RRadio.TabIndex = 9; + RRadio.Text = "R"; + RRadio.UseVisualStyleBackColor = true; + RRadio.CheckedChanged += RRadio_CheckedChanged; + // + // GTextBox + // + GTextBox.Location = new System.Drawing.Point(372, 158); + GTextBox.Name = "GTextBox"; + GTextBox.Size = new System.Drawing.Size(35, 23); + GTextBox.TabIndex = 12; + GTextBox.Text = "0"; + GTextBox.TextChanged += GTextBox_TextChanged; + // + // GRadio + // + GRadio.AutoSize = true; + GRadio.Location = new System.Drawing.Point(334, 159); + GRadio.Name = "GRadio"; + GRadio.Size = new System.Drawing.Size(33, 19); + GRadio.TabIndex = 11; + GRadio.Text = "G"; + GRadio.UseVisualStyleBackColor = true; + GRadio.CheckedChanged += GRadio_CheckedChanged; + // + // BTextBox + // + BTextBox.Location = new System.Drawing.Point(372, 187); + BTextBox.Name = "BTextBox"; + BTextBox.Size = new System.Drawing.Size(35, 23); + BTextBox.TabIndex = 14; + BTextBox.Text = "0"; + BTextBox.TextChanged += BTextBox_TextChanged; + // + // BRadio + // + BRadio.AutoSize = true; + BRadio.Location = new System.Drawing.Point(334, 188); + BRadio.Name = "BRadio"; + BRadio.Size = new System.Drawing.Size(32, 19); + BRadio.TabIndex = 13; + BRadio.Text = "B"; + BRadio.UseVisualStyleBackColor = true; + BRadio.CheckedChanged += BRadio_CheckedChanged; + // + // HexTextBox + // + HexTextBox.Location = new System.Drawing.Point(372, 249); + HexTextBox.Name = "HexTextBox"; + HexTextBox.Size = new System.Drawing.Size(58, 23); + HexTextBox.TabIndex = 18; + HexTextBox.Text = "000000"; + HexTextBox.TextChanged += HexTextBox_TextChanged; + // + // HexLabel + // + HexLabel.AutoSize = true; + HexLabel.Location = new System.Drawing.Point(350, 252); + HexLabel.Name = "HexLabel"; + HexLabel.Size = new System.Drawing.Size(14, 15); + HexLabel.TabIndex = 17; + HexLabel.Text = "#"; + // + // ATextBox + // + ATextBox.Location = new System.Drawing.Point(372, 216); + ATextBox.Name = "ATextBox"; + ATextBox.Size = new System.Drawing.Size(35, 23); + ATextBox.TabIndex = 16; + ATextBox.Text = "255"; + ATextBox.TextChanged += ATextBox_TextChanged; + // + // ARadio + // + ARadio.AutoSize = true; + ARadio.Location = new System.Drawing.Point(333, 217); + ARadio.Name = "ARadio"; + ARadio.Size = new System.Drawing.Size(33, 19); + ARadio.TabIndex = 15; + ARadio.Text = "A"; + ARadio.UseVisualStyleBackColor = true; + ARadio.CheckedChanged += ARadio_CheckedChanged; + // + // NewLabel + // + NewLabel.AutoSize = true; + NewLabel.Location = new System.Drawing.Point(24, 278); + NewLabel.Name = "NewLabel"; + NewLabel.Size = new System.Drawing.Size(31, 15); + NewLabel.TabIndex = 19; + NewLabel.Text = "New"; + // + // OldLabel + // + OldLabel.AutoSize = true; + OldLabel.Location = new System.Drawing.Point(75, 278); + OldLabel.Name = "OldLabel"; + OldLabel.Size = new System.Drawing.Size(26, 15); + OldLabel.TabIndex = 20; + OldLabel.Text = "Old"; + // + // PaletteLabel + // + PaletteLabel.AutoSize = true; + PaletteLabel.Location = new System.Drawing.Point(143, 278); + PaletteLabel.Name = "PaletteLabel"; + PaletteLabel.Size = new System.Drawing.Size(90, 15); + PaletteLabel.TabIndex = 21; + PaletteLabel.Text = "Palette / Recent"; + // + // UpdateTimer + // + UpdateTimer.Interval = 50; + UpdateTimer.Tick += UpdateTimer_Tick; + // + // ColourPicker + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.PaletteLabel); + this.Controls.Add(this.OldLabel); + this.Controls.Add(this.NewLabel); + this.Controls.Add(this.ARadio); + this.Controls.Add(this.ATextBox); + this.Controls.Add(this.HexLabel); + this.Controls.Add(this.HexTextBox); + this.Controls.Add(this.BTextBox); + this.Controls.Add(this.BRadio); + this.Controls.Add(this.GTextBox); + this.Controls.Add(this.GRadio); + this.Controls.Add(this.RTextBox); + this.Controls.Add(this.RRadio); + this.Controls.Add(this.VLabel); + this.Controls.Add(this.VTextBox); + this.Controls.Add(this.VRadio); + this.Controls.Add(this.SLabel); + this.Controls.Add(this.STextBox); + this.Controls.Add(this.SRadio); + this.Controls.Add(this.HLabel); + this.Controls.Add(this.HTextBox); + this.Controls.Add(this.HRadio); + this.DoubleBuffered = true; + this.Name = "ColourPicker"; + this.Size = new System.Drawing.Size(450, 360); + this.MouseDown += ColourPicker_MouseDown; + this.MouseMove += ColourPicker_MouseMove; + this.MouseUp += ColourPicker_MouseUp; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.RadioButton HRadio; + private System.Windows.Forms.TextBox HTextBox; + private System.Windows.Forms.Label HLabel; + private System.Windows.Forms.Label SLabel; + private System.Windows.Forms.TextBox STextBox; + private System.Windows.Forms.RadioButton SRadio; + private System.Windows.Forms.Label VLabel; + private System.Windows.Forms.TextBox VTextBox; + private System.Windows.Forms.RadioButton VRadio; + private System.Windows.Forms.TextBox RTextBox; + private System.Windows.Forms.RadioButton RRadio; + private System.Windows.Forms.TextBox GTextBox; + private System.Windows.Forms.RadioButton GRadio; + private System.Windows.Forms.TextBox BTextBox; + private System.Windows.Forms.RadioButton BRadio; + private System.Windows.Forms.TextBox HexTextBox; + private System.Windows.Forms.Label HexLabel; + private System.Windows.Forms.TextBox ATextBox; + private System.Windows.Forms.RadioButton ARadio; + private System.Windows.Forms.Label NewLabel; + private System.Windows.Forms.Label OldLabel; + private System.Windows.Forms.Label PaletteLabel; + private System.Windows.Forms.Timer UpdateTimer; + } +} diff --git a/CodeWalker/Utils/ColourPicker.cs b/CodeWalker/Utils/ColourPicker.cs new file mode 100644 index 0000000..55e7437 --- /dev/null +++ b/CodeWalker/Utils/ColourPicker.cs @@ -0,0 +1,866 @@ +using CodeWalker.Properties; +using SharpDX; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Imaging; +using System.Globalization; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Color = System.Drawing.Color; +using Rectangle = System.Drawing.Rectangle; + +namespace CodeWalker.Utils +{ + public partial class ColourPicker : UserControl + { + public Color SelectedColour + { + get => Colour; + set => SetColour(value, true, true); + } + private Color OldColour = Color.Black; + private Color Colour = Color.Black; + private ColourComponent ColourMode = ColourComponent.H; + private Bitmap MainGradient; + private Bitmap SideGradient; + private int HVal = 0; + private int SVal = 0; + private int VVal = 0; + private int RVal = 0; + private int GVal = 0; + private int BVal = 0; + private int AVal = 255; + private const float Deg255 = 360.0f / 255.0f; + private const float Hun255 = 100.0f / 255.0f; + private const float One255 = 1.0f / 255.0f; + private const float One100 = 1.0f / 100.0f; + private bool UpdatingTextboxes = false; + private float CircleThickness = 1.0f; + private float CircleRadius = 5.8f; + private int CircleBox = 13; + private int CircleOffset = 6; + private const float CircleH = 255.0f / 360.0f; + private const float CircleSV = 255.0f / 100.0f; + private Bitmap CircleBlack; + private Bitmap CircleWhite; + private int SliderBox = 13; + private int SliderOffset = 6; + private Bitmap SliderL; + private Bitmap SliderR; + private bool MainDrag; + private bool SideDrag; + private Color[] CustomColours; + private Color[] RecentColours; + private static Color[] DefaultColours = + { + NewColour(255,0,0,255),NewColour(255,255,0,255),NewColour(0,255,0,255), + NewColour(0,255,255,255),NewColour(0,0,255,255),NewColour(255,0,255,255), + NewColour(255,255,255,255),NewColour(191,191,191,255),NewColour(127,127,127,255), + NewColour(63,63,63,255),NewColour(31,31,31,255),NewColour(0,0,0,255), + NewColour(255,255,255,255),NewColour(238,238,238,255),NewColour(221,221,221,255), + NewColour(204,204,204,255),NewColour(187,187,187,255),NewColour(170,170,170,255), + NewColour(153,153,153,255),NewColour(136,136,136,255),NewColour(119,119,119,255), + NewColour(102,102,102,255),NewColour(85,85,85,255),NewColour(68,68,68,255), + }; + private static Color NewColour(int r, int g, int b, int a) + { + return Color.FromArgb(a, r, g, b); + } + private static Color NewColour(Vector4 v) + { + return Color.FromArgb(ToByte(v.W), ToByte(v.X), ToByte(v.Y), ToByte(v.Z)); + } + private static Color ColourFromHexString(string hex) + { + uint.TryParse(hex, NumberStyles.AllowHexSpecifier, null, out var u); + return NewColour((byte)(u >> 24), (byte)(u >> 16), (byte)(u >> 8), (byte)u); + } + private static Color ColourFromHexRGBString(string str) + { + var rstr = str.Length > 1 ? str.Substring(0, 2) : "00"; + var gstr = str.Length > 3 ? str.Substring(2, 2) : "00"; + var bstr = str.Length > 5 ? str.Substring(4, 2) : "00"; + int.TryParse(rstr, NumberStyles.AllowHexSpecifier, null, out var r); + int.TryParse(gstr, NumberStyles.AllowHexSpecifier, null, out var g); + int.TryParse(bstr, NumberStyles.AllowHexSpecifier, null, out var b); + var a = 255; + var c = NewColour(r, g, b, a); + return c; + } + private static string ColourToHexString(Color c) + { + var u = (uint)(c.A | (c.B << 8) | (c.G << 16) | (c.R << 24)); + var s = u.ToString("X").PadLeft(8, '0'); + return s; + } + private static string ColourToHexRGBString(Color c) + { + var u = (uint)(c.B | (c.G << 8) | (c.R << 16)); + var s = u.ToString("X").PadLeft(6, '0'); + return s; + } + private static Vector4 ColourFFromHSB(float hue, float saturation, float brightness, float alpha = 1.0f) + { + var h = Math.Max(0, Math.Min(360.0f, hue)); + var s = Math.Max(0, Math.Min(1.0f, saturation)); + var b = Math.Max(0, Math.Min(1.0f, brightness)); + var a = Math.Max(0, Math.Min(1.0f, alpha)); + if (Math.Abs(s) < 1e-6f) return new Vector4(b, b, b, a); + var sectorPos = h / 60.0f; // the argb wheel consists of 6 sectors. Figure out which sector you're in. + var sectorNum = (int)Math.Floor(sectorPos); + var sectorFrac = sectorPos - sectorNum; + var p = b * (1.0f - s); // calculate values for the three axes of the argb. + var q = b * (1.0f - (s * sectorFrac)); + var t = b * (1.0f - (s * (1.0f - sectorFrac))); + switch (sectorNum) // assign the fractional colors to r, g, and b based on the sector the angle is in. + { + case 0: return new Vector4(b, t, p, a); + case 1: return new Vector4(q, b, p, a); + case 2: return new Vector4(p, b, t, a); + case 3: return new Vector4(p, q, b, a); + case 4: return new Vector4(t, p, b, a); + case 5: return new Vector4(b, p, q, a); + } + return new Vector4(b, t, p, a); + } + private static Color ColourFromHSB(float hue, float saturation, float brightness, int alpha = 255) + { + var f = ColourFFromHSB(hue, saturation, brightness); + var c = NewColour(ToByte(f.X), ToByte(f.Y), ToByte(f.Z), alpha); + return c; + } + private static Vector3 ColourToHSB(Color c) + { + var r = c.R / 255.0f; + var g = c.G / 255.0f; + var b = c.B / 255.0f; + var max = Math.Max(Math.Max(r, g), b); + var min = Math.Min(Math.Min(r, g), b); + var rng = max - min; + var h = (Math.Abs(rng) < 1e-6f) ? 0 : + (Math.Abs(max - r) < 1e-6f) ? + ((60 * (g - b)) / rng) + ((g >= b) ? 0 : 360) : + (Math.Abs(max - g) < 1e-6f) ? + ((60 * (b - r)) / rng) + 120 : + (Math.Abs(max - b) < 1e-6f) ? + ((60 * (r - g)) / rng) + 240 : 0; + var s = (Math.Abs(max) < 1e-6f) ? 0 : 1 - (min / max); + return new Vector3(FloatUtil.Clamp(h, 0, 360), FloatUtil.Saturate(s), FloatUtil.Saturate(max)); + } + private static byte ToByte(float component) + { + var value = (int)(component * 255.0f); + return (byte)(value < 0 ? 0 : value > 255 ? 255 : value); + } + + private enum ColourComponent + { + H, S, V, R, G, B, A, Hex, None + } + + + + + public ColourPicker() + { + InitializeComponent(); + InitPaletteColours(); + InitBitmaps(); + UpdateGradients(); + Disposed += ColourPicker_Disposed; + } + + private void InitBitmaps() + { + MainGradient = new Bitmap(256, 256); + SideGradient = new Bitmap(20, 256); + CircleBlack = CreateCircleBitmap(Color.Black); + CircleWhite = CreateCircleBitmap(Color.White); + SliderL = CreateSliderBitmap(true); + SliderR = CreateSliderBitmap(false); + } + private void DisposeBitmaps() + { + MainGradient?.Dispose(); + MainGradient = null; + SideGradient?.Dispose(); + SideGradient = null; + CircleBlack?.Dispose(); + CircleBlack = null; + CircleWhite?.Dispose(); + CircleWhite = null; + SliderL?.Dispose(); + SliderL = null; + SliderR?.Dispose(); + SliderR = null; + } + private Bitmap CreateCircleBitmap(Color colour) + { + var c = colour; + var b = new Bitmap(CircleBox, CircleBox); + var cen = new Vector2(CircleOffset); + for (int y = 0; y < CircleBox; y++) + { + for (int x = 0; x < CircleBox; x++) + { + var p = new Vector2(x, y) - cen; + var r = p.Length(); + var t = Math.Abs(r - CircleRadius) / CircleThickness; + var a = FloatUtil.Saturate(1 - t); + b.SetPixel(x, y, Color.FromArgb(ToByte(a), c.R, c.G, c.B)); + } + } + return b; + } + private Bitmap CreateSliderBitmap(bool dirL) + { + var outlineThickInv = 0.9f; + var p1 = new Vector2(1.5f, 1.5f); + var p2 = new Vector2(1.5f, SliderBox - 2.5f); + var p3 = new Vector2(SliderBox - 1.0f, SliderBox * 0.5f - 0.5f); + var b = new Bitmap(SliderBox, SliderBox); + for (int y = 0; y < SliderBox; y++) + { + for (int x = 0; x < SliderBox; x++) + { + var v = new Vector2(x, y); + var d1 = LineMath.DistanceFieldTest(v, p1, p2, out var w1); + var d2 = LineMath.DistanceFieldTest(v, p2, p3, out var w2); + var d3 = LineMath.DistanceFieldTest(v, p3, p1, out var w3); + var d = Math.Min(Math.Min(d1, d2), d3); + var w = w1 + w2 + w3; + var dw = (w != 0) ? d : -d; + var c1 = (dw > 0) ? Vector4.One : Vector4.Zero; + var a2 = FloatUtil.Saturate(1.0f - (d * outlineThickInv)); + var c2 = new Vector4(0, 0, 0, a2); + var c = NewColour(Vector4.Lerp(c1, c2, a2)); + var px = dirL ? x : SliderBox - x - 1; + b.SetPixel(px, y, c); + } + } + return b; + } + private Color[] GetColoursSetting(string str) + { + if (string.IsNullOrEmpty(str)) return null; + var strs = str.Split(' '); + var colours = new List(); + foreach (var item in strs) + { + var itemt = item.Trim(); + if (string.IsNullOrEmpty(itemt)) continue; + var c = ColourFromHexString(itemt); + if (c != default) + { + colours.Add(c); + } + } + if (colours.Count == 0) return null; + return colours.ToArray(); + } + private string SetColoursSetting(Color[] colours) + { + if ((colours == null) || (colours.Length == 0)) + { + return ""; + } + var sb = new StringBuilder(); + foreach (var c in colours) + { + sb.Append(ColourToHexString(c)); + sb.Append(" "); + } + var val = sb.ToString(); + return val; + } + private void InitPaletteColours() + { + var s = Settings.Default; + var c = GetColoursSetting(s.ColourPickerCustomColours); + var r = GetColoursSetting(s.ColourPickerRecentColours); + CustomColours = new Color[12]; + RecentColours = new Color[12]; + for (int i = 0; i < 12; i++) + { + CustomColours[i] = ((c != null) && (i < c.Length)) ? c[i] : DefaultColours[i]; + RecentColours[i] = ((r != null) && (i < r.Length)) ? r[i] : DefaultColours[i + 12]; + } + } + private void UpdateCustomColour(int i) + { + if (i < 0) return; + if (i > 11) return; + CustomColours[i] = Colour; + Settings.Default.ColourPickerCustomColours = SetColoursSetting(CustomColours); + Invalidate(); + } + private void UpdateRecentColour(int i) + { + if (i < 0) return; + if (i > 11) return; + RecentColours[i] = Colour; + Settings.Default.ColourPickerRecentColours = SetColoursSetting(RecentColours); + Invalidate(); + } + public void SaveRecentColour() + { + //push the current colour to the front of the recent colours list, if it's not in there already + if (RecentColours == null) return; + if (Colour == OldColour) return;//don't try save the old colour + foreach (var rc in RecentColours) + { + if (rc == Colour) return;//it's already in the list, abort + } + for (int i = RecentColours.Length - 1; i > 0; i--) + { + RecentColours[i] = RecentColours[i - 1]; + } + RecentColours[0] = Colour; + Settings.Default.ColourPickerRecentColours = SetColoursSetting(RecentColours); + } + + private void SetColourMode(ColourComponent m) + { + ColourMode = m; + UpdateGradients(); + } + + private void SetColourComponentEvent(ColourComponent c, string str) + { + if (UpdatingTextboxes) return; + SetColourComponent(c, str, false); + } + private void SetColourComponent(ColourComponent c, string str, bool updateTextbox) + { + int.TryParse(str, out var v); + SetColourComponent(c, v, updateTextbox); + } + private void SetColourComponent(ColourComponent c, int v, bool updateTextbox) + { + switch (c) + { + case ColourComponent.H: HVal = v; break; + case ColourComponent.S: SVal = v; break; + case ColourComponent.V: VVal = v; break; + case ColourComponent.R: RVal = v; break; + case ColourComponent.G: GVal = v; break; + case ColourComponent.B: BVal = v; break; + case ColourComponent.A: AVal = v; break; + } + switch (c) + { + case ColourComponent.H: + case ColourComponent.S: + case ColourComponent.V: + Colour = ColourFromHSB(HVal, SVal * One100, VVal * One100, AVal); + RVal = Colour.R; + GVal = Colour.G; + BVal = Colour.B; + break; + default: + Colour = NewColour(RVal, GVal, BVal, AVal); + var hsb = ColourToHSB(Colour); + HVal = (int)(hsb.X); + SVal = (int)(hsb.Y * 100); + VVal = (int)(hsb.Z * 100); + break; + } + UpdateGradients(); + UpdateTextboxes(updateTextbox ? ColourComponent.None : c); + } + private void SetColour(Color c, bool updateTextbox = true, bool origVal = false) + { + Colour = c; + if (origVal) OldColour = c; + var hsb = ColourToHSB(Colour); + HVal = (int)(hsb.X); + SVal = (int)(hsb.Y * 100); + VVal = (int)(hsb.Z * 100); + RVal = c.R; + GVal = c.G; + BVal = c.B; + AVal = c.A; + UpdateGradients(); + if (updateTextbox) + { + UpdateTextboxes(ColourComponent.None); + } + } + private void SetMainColour(int x, int y) + { + x -= 16; + y -= 16; + y = 255 - y; + if (x < 0) x = 0; + if (y < 0) y = 0; + if (x > 255) x = 255; + if (y > 255) y = 255; + var c = GetMainColour(x, y); + var hsb = ColourToHSB(c); + Colour = c; + switch (ColourMode) + { + case ColourComponent.H: + SVal = (int)Math.Round(x * Hun255); + VVal = (int)Math.Round(y * Hun255); + break; + case ColourComponent.S: + HVal = (int)Math.Round(x * Deg255); + VVal = (int)Math.Round(y * Hun255); + break; + case ColourComponent.V: + HVal = (int)Math.Round(x * Deg255); + SVal = (int)Math.Round(y * Hun255); + break; + default: + HVal = (int)(hsb.X); + SVal = (int)(hsb.Y * 100); + VVal = (int)(hsb.Z * 100); + break; + } + RVal = c.R; + GVal = c.G; + BVal = c.B; + AVal = c.A; + UpdateGradients(); + UpdateTextboxes(ColourComponent.None); + } + private void SetSideColour(int x, int y) + { + x -= 16; + y -= 16; + y = 255 - y; + if (y < 0) y = 0; + if (y > 255) y = 255; + var c = GetSideColour(x, y, false); + var hsb = ColourToHSB(c); + Colour = c; + switch (ColourMode) + { + case ColourComponent.H: + HVal = (int)Math.Round(y * Deg255); + break; + case ColourComponent.S: + SVal = (int)Math.Round(y * Hun255); + break; + case ColourComponent.V: + VVal = (int)Math.Round(y * Hun255); + break; + default: + HVal = (int)(hsb.X); + SVal = (int)(hsb.Y * 100); + VVal = (int)(hsb.Z * 100); + break; + } + RVal = c.R; + GVal = c.G; + BVal = c.B; + AVal = c.A; + UpdateGradients(); + UpdateTextboxes(ColourComponent.None); + } + + private void UpdateTextboxes(ColourComponent ignore) + { + UpdatingTextboxes = true; + if (ignore != ColourComponent.H) HTextBox.Text = HVal.ToString(); + if (ignore != ColourComponent.S) STextBox.Text = SVal.ToString(); + if (ignore != ColourComponent.V) VTextBox.Text = VVal.ToString(); + if (ignore != ColourComponent.R) RTextBox.Text = RVal.ToString(); + if (ignore != ColourComponent.G) GTextBox.Text = GVal.ToString(); + if (ignore != ColourComponent.B) BTextBox.Text = BVal.ToString(); + if (ignore != ColourComponent.A) ATextBox.Text = AVal.ToString(); + if (ignore != ColourComponent.Hex) HexTextBox.Text = ColourToHexRGBString(Colour); + UpdatingTextboxes = false; + } + + private void UpdateGradients() + { + if (MainDrag || SideDrag) + { + UpdateTimer.Enabled = true; + Invalidate(); + } + else + { + UpdateGradientsProc(); + } + } + private void UpdateGradientsProc() + { + + var mg = new byte[256 * 256 * 4]; + var sg = new byte[256 * 20 * 4]; + //Parallel.For(0, 256, y => + for (int y = 0; y < 256; y++) + { + var iy = 255 - y; + for (int x = 0; x < 256; x++) + { + var c = GetMainColour(x, iy); + //MainGradient.SetPixel(x, y, Color.FromArgb(c.A, c.R, c.G, c.B)); + var i = ((y * 256) + x) * 4; + mg[i + 0] = c.B; + mg[i + 1] = c.G; + mg[i + 2] = c.R; + mg[i + 3] = c.A; + } + for (int x = 0; x < 20; x++) + { + var c = GetSideColour(x, iy, true); + //SideGradient.SetPixel(x, y, Color.FromArgb(c.A, c.R, c.G, c.B)); + var i = ((y * 20) + x) * 4; + sg[i + 0] = c.B; + sg[i + 1] = c.G; + sg[i + 2] = c.R; + sg[i + 3] = c.A; + } + }//); + + var mbmp = MainGradient.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); + var mptr = mbmp.Scan0; + Marshal.Copy(mg, 0, mptr, mg.Length); + MainGradient.UnlockBits(mbmp); + + var sbmp = SideGradient.LockBits(new Rectangle(0, 0, 20, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); + var sptr = sbmp.Scan0; + Marshal.Copy(sg, 0, sptr, sg.Length); + SideGradient.UnlockBits(sbmp); + + Invalidate(); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private Color GetMainColour(int x, int y) + { + switch (ColourMode) + { + case ColourComponent.H: return ColourFromHSB(HVal, x * One255, y * One255, AVal); + case ColourComponent.S: return ColourFromHSB(x * Deg255, SVal * One100, y * One255, AVal); + case ColourComponent.V: return ColourFromHSB(x * Deg255, y * One255, VVal * One100, AVal); + case ColourComponent.R: return NewColour(RVal, x, y, AVal); + case ColourComponent.G: return NewColour(x, GVal, y, AVal); + case ColourComponent.B: return NewColour(x, y, BVal, AVal); + case ColourComponent.A: return NewColour(RVal, GVal, BVal, y); + default: return NewColour(x, y, 0, AVal); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private Color GetSideColour(int x, int y, bool preview) + { + switch (ColourMode) + { + case ColourComponent.H: return preview ? ColourFromHSB(y * Deg255, 1, 1, AVal) : ColourFromHSB(y * Deg255, SVal * One100, VVal * One100, AVal); + case ColourComponent.S: return ColourFromHSB(HVal, y * One255, VVal * One100, AVal); + case ColourComponent.V: return ColourFromHSB(HVal, SVal * One100, y * One255, AVal); + case ColourComponent.R: return NewColour(y, GVal, BVal, AVal); + case ColourComponent.G: return NewColour(RVal, y, BVal, AVal); + case ColourComponent.B: return NewColour(RVal, GVal, y, AVal); + case ColourComponent.A: return NewColour(RVal, GVal, BVal, y); + default: return NewColour(x, y, 0, AVal); + } + } + + private int GetCircleX() + { + switch (ColourMode) + { + case ColourComponent.H: return (int)Math.Round(SVal * CircleSV); + case ColourComponent.S: return (int)Math.Round(HVal * CircleH); + case ColourComponent.V: return (int)Math.Round(HVal * CircleH); + case ColourComponent.R: return GVal; + case ColourComponent.G: return RVal; + case ColourComponent.B: return RVal; + case ColourComponent.A: return 0; + default: return RVal; + } + } + private int GetCircleY() + { + switch (ColourMode) + { + case ColourComponent.H: return (int)Math.Round(VVal * CircleSV); + case ColourComponent.S: return (int)Math.Round(VVal * CircleSV); + case ColourComponent.V: return (int)Math.Round(SVal * CircleSV); + case ColourComponent.R: return BVal; + case ColourComponent.G: return BVal; + case ColourComponent.B: return GVal; + case ColourComponent.A: return AVal; + default: return GVal; + } + } + private int GetSliderY() + { + switch (ColourMode) + { + case ColourComponent.H: return (int)Math.Round(HVal * CircleH); + case ColourComponent.S: return (int)Math.Round(SVal * CircleSV); + case ColourComponent.V: return (int)Math.Round(VVal * CircleSV); + case ColourComponent.R: return RVal; + case ColourComponent.G: return GVal; + case ColourComponent.B: return BVal; + case ColourComponent.A: return AVal; + default: return RVal; + } + } + + private bool InMainImage(int x, int y) + { + if (x < 16) return false; + if (y < 16) return false; + if (x > 271) return false; + if (y > 271) return false; + return true; + } + private bool InSideImage(int x, int y) + { + if (x < 280) return false; + if (y < 16) return false; + if (x > 320) return false; + if (y > 271) return false; + return true; + } + + private int GetCustomColourIndex(int x, int y) + { + if (y < 296) return -1; + if (y > (296 + 23)) return -1; + var xr = x - 130; + if (xr < 0) return -1; + var xi = xr / 26; + if (xi > 11) return -1; + var t = xr - (xi * 26); + if (t > 23) return -1; + return xi; + } + private int GetRecentColourIndex(int x, int y) + { + if (y < (296 + 26)) return -1; + if (y > (296 + 26 + 23)) return -1; + var xr = x - 130; + if (xr < 0) return -1; + var xi = xr / 26; + if (xi > 11) return -1; + var t = xr - (xi * 26); + if (t > 23) return -1; + return xi; + } + + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + if (MainGradient == null) return; + + var g = e.Graphics; + + g.DrawImage(MainGradient, 16, 16); + g.DrawImage(SideGradient, 290, 16); + + var circImg = (VVal >= 80) ? CircleBlack : CircleWhite; + var cx = 16 + GetCircleX() - CircleOffset; + var cy = 16 - GetCircleY() - CircleOffset + 255; + g.SetClip(new Rectangle(16, 16, 256, 256)); + g.DrawImage(circImg, cx, cy); + g.ResetClip(); + + + var sy = 16 - GetSliderY() - SliderOffset + 255; + var sxL = 290 - SliderBox; + var sxR = 290 + 20; + g.DrawImage(SliderL, sxL, sy); + g.DrawImage(SliderR, sxR, sy); + + + using (var ob = new SolidBrush(Color.FromArgb(OldColour.A, OldColour.R, OldColour.G, OldColour.B))) + { + using (var nb = new SolidBrush(Color.FromArgb(Colour.A, Colour.R, Colour.G, Colour.B))) + { + g.FillRectangle(nb, 16, 296, 50, 50); + g.FillRectangle(ob, 66, 296, 50, 50); + + for (int y = 0; y < 2; y++) + { + var carr = (y == 0) ? CustomColours : RecentColours; + for (int x = 0; x < 12; x++) + { + var c = ((carr != null) && (x < carr.Length)) ? carr[x] : NewColour(0, 0, 0, 255); + using (var b = new SolidBrush(Color.FromArgb(c.A, c.R, c.G, c.B))) + { + g.FillRectangle(b, 130 + (x * 26), 296 + (y * 26), 24, 24); + } + } + } + } + } + + } + + + + private void HRadio_CheckedChanged(object sender, EventArgs e) + { + if (HRadio.Checked) SetColourMode(ColourComponent.H); + } + + private void SRadio_CheckedChanged(object sender, EventArgs e) + { + if (SRadio.Checked) SetColourMode(ColourComponent.S); + } + + private void VRadio_CheckedChanged(object sender, EventArgs e) + { + if (VRadio.Checked) SetColourMode(ColourComponent.V); + } + + private void RRadio_CheckedChanged(object sender, EventArgs e) + { + if (RRadio.Checked) SetColourMode(ColourComponent.R); + } + + private void GRadio_CheckedChanged(object sender, EventArgs e) + { + if (GRadio.Checked) SetColourMode(ColourComponent.G); + } + + private void BRadio_CheckedChanged(object sender, EventArgs e) + { + if (BRadio.Checked) SetColourMode(ColourComponent.B); + } + + private void ARadio_CheckedChanged(object sender, EventArgs e) + { + if (ARadio.Checked) SetColourMode(ColourComponent.A); + } + + private void HTextBox_TextChanged(object sender, EventArgs e) + { + SetColourComponentEvent(ColourComponent.H, HTextBox.Text); + } + + private void STextBox_TextChanged(object sender, EventArgs e) + { + SetColourComponentEvent(ColourComponent.S, STextBox.Text); + } + + private void VTextBox_TextChanged(object sender, EventArgs e) + { + SetColourComponentEvent(ColourComponent.V, VTextBox.Text); + } + + private void RTextBox_TextChanged(object sender, EventArgs e) + { + SetColourComponentEvent(ColourComponent.R, RTextBox.Text); + } + + private void GTextBox_TextChanged(object sender, EventArgs e) + { + SetColourComponentEvent(ColourComponent.G, GTextBox.Text); + } + + private void BTextBox_TextChanged(object sender, EventArgs e) + { + SetColourComponentEvent(ColourComponent.B, BTextBox.Text); + } + + private void ATextBox_TextChanged(object sender, EventArgs e) + { + SetColourComponentEvent(ColourComponent.A, ATextBox.Text); + } + + private void HexTextBox_TextChanged(object sender, EventArgs e) + { + if (UpdatingTextboxes) return; + var c = ColourFromHexRGBString(HexTextBox.Text); + SetColour(c, false); + UpdateTextboxes(ColourComponent.Hex); + } + + private void UpdateTimer_Tick(object sender, EventArgs e) + { + UpdateTimer.Enabled = false; + UpdateGradientsProc(); + } + + private void ColourPicker_MouseDown(object sender, MouseEventArgs e) + { + if (InMainImage(e.X, e.Y)) + { + SetMainColour(e.X, e.Y); + MainDrag = true; + } + else if (InSideImage(e.X, e.Y)) + { + SetSideColour(e.X, e.Y); + SideDrag = true; + } + else + { + var ci = GetCustomColourIndex(e.X, e.Y); + var ri = GetRecentColourIndex(e.X, e.Y); + if (ci != -1) + { + if (e.Button == MouseButtons.Right) + { + UpdateCustomColour(ci); + } + else + { + SetColour(CustomColours[ci]); + } + } + else if (ri != -1) + { + if (e.Button == MouseButtons.Right) + { + UpdateRecentColour(ri); + } + else + { + SetColour(RecentColours[ri]); + } + } + } + } + + private void ColourPicker_MouseUp(object sender, MouseEventArgs e) + { + if (MainDrag) + { + SetMainColour(e.X, e.Y); + } + else if (SideDrag) + { + SetSideColour(e.X, e.Y); + } + MainDrag = false; + SideDrag = false; + } + + private void ColourPicker_MouseMove(object sender, MouseEventArgs e) + { + if (MainDrag) + { + SetMainColour(e.X, e.Y); + } + else if (SideDrag) + { + SetSideColour(e.X, e.Y); + } + } + + private void ColourPicker_Disposed(object sender, EventArgs e) + { + DisposeBitmaps(); + } + } +} diff --git a/CodeWalker/Utils/ColourPicker.resx b/CodeWalker/Utils/ColourPicker.resx new file mode 100644 index 0000000..05f1355 --- /dev/null +++ b/CodeWalker/Utils/ColourPicker.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/CodeWalker/Utils/ColourPickerForm.Designer.cs b/CodeWalker/Utils/ColourPickerForm.Designer.cs new file mode 100644 index 0000000..c8c657f --- /dev/null +++ b/CodeWalker/Utils/ColourPickerForm.Designer.cs @@ -0,0 +1,92 @@ +namespace CodeWalker.Utils +{ + partial class ColourPickerForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #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() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ColourPickerForm)); + Picker = new ColourPicker(); + ButtonOk = new System.Windows.Forms.Button(); + ButtonCancel = new System.Windows.Forms.Button(); + SuspendLayout(); + // + // Picker + // + Picker.Location = new System.Drawing.Point(0, 0); + Picker.Name = "Picker"; + Picker.Size = new System.Drawing.Size(450, 360); + Picker.TabIndex = 0; + // + // ButtonOk + // + ButtonOk.Location = new System.Drawing.Point(229, 362); + ButtonOk.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + ButtonOk.Name = "ButtonOk"; + ButtonOk.Size = new System.Drawing.Size(88, 27); + ButtonOk.TabIndex = 4; + ButtonOk.Text = "Ok"; + ButtonOk.UseVisualStyleBackColor = true; + ButtonOk.Click += ButtonOk_Click; + // + // ButtonCancel + // + ButtonCancel.Location = new System.Drawing.Point(352, 362); + ButtonCancel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + ButtonCancel.Name = "ButtonCancel"; + ButtonCancel.Size = new System.Drawing.Size(88, 27); + ButtonCancel.TabIndex = 3; + ButtonCancel.Text = "Cancel"; + ButtonCancel.UseVisualStyleBackColor = true; + ButtonCancel.Click += ButtonCancel_Click; + // + // ColourPickerForm + // + AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(454, 398); + Controls.Add(ButtonOk); + Controls.Add(ButtonCancel); + Controls.Add(Picker); + DoubleBuffered = true; + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + MaximizeBox = false; + MinimizeBox = false; + Name = "ColourPickerForm"; + Text = "Colour Picker - CodeWalker by dexyfex"; + FormClosing += ColourPickerForm_FormClosing; + Load += ColourPickerForm_Load; + ResumeLayout(false); + } + + #endregion + + private ColourPicker Picker; + private System.Windows.Forms.Button ButtonOk; + private System.Windows.Forms.Button ButtonCancel; + } +} \ No newline at end of file diff --git a/CodeWalker/Utils/ColourPickerForm.cs b/CodeWalker/Utils/ColourPickerForm.cs new file mode 100644 index 0000000..6138d2f --- /dev/null +++ b/CodeWalker/Utils/ColourPickerForm.cs @@ -0,0 +1,54 @@ +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 CodeWalker.Utils +{ + public partial class ColourPickerForm : Form + { + public Color SelectedColour + { + get => Picker.SelectedColour; + set => Picker.SelectedColour = value; + } + + public ColourPickerForm() + { + InitializeComponent(); + } + + private void ColourPickerForm_Load(object sender, EventArgs e) + { + //var loc = Vector2.Max(Vector2.Zero, LocationSetting.GetVector2()); + //if (loc != Vector2.Zero) + //{ + // Location = new Point((int)loc.X, (int)loc.Y); + //} + } + + private void ColourPickerForm_FormClosing(object sender, FormClosingEventArgs e) + { + //var l = Location; + //LocationSetting.Set(new Vector2(l.X, l.Y)); + } + + private void ButtonOk_Click(object sender, EventArgs e) + { + Picker.SaveRecentColour(); + DialogResult = DialogResult.OK; + Close(); + } + + private void ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/CodeWalker/Utils/ColourPickerForm.resx b/CodeWalker/Utils/ColourPickerForm.resx new file mode 100644 index 0000000..0960cbe --- /dev/null +++ b/CodeWalker/Utils/ColourPickerForm.resx @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAMAICAAAAAAGACoDAAANgAAABAQAAAAABgAaAMAAN4MAABAQAAAAAAYACgyAABGEAAAKAAAACAA + AABAAAAAAQAYAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////v8/u3v+Pn6//7+//////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //7+/vX3/rzA3OHl9fz9//////////////////////////////////////////////////////////// + //////////////////////////////////////////////////7//+zv+3Z6qcLI5Pr7//////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////7+/+br+15in6+33vf5//////////////////7+//7+//////////////////// + //////////////////////////////3+//v8//v8//3+//////////////////////7+/+Ho+1dana20 + 4/b4//////////z9//P2/+Tp/ezw/vz9//////////////////////////////////////////7///X4 + /9Pa+tPa+/H1//z9//////////////////7+/93k+SsscaSr3PX3//////7+//L1/7W98AcWgrvC8Pj6 + //////////////////////////////////////////7+/+bs/xohiAEJdrvF9+7y//z9//////////// + //7+/9rh+CEkapmh0/T3//////j6/9HZ/AEHcgEEb9LZ+/r7//////////////////////////////// + //////////7//+/z/3F+zAAAXwQLcZai3fb4//////////////3+/97l/E9Tmaau4fT3/////+/0/1dd + sAAAV7a/8/H1//7+//////////////////////////////////////////////r8/+jv/46Y3QUUf6Ot + 5PX4//////////////3+/9zj+3Z6wLe/7fX4//////D0/212xnaAzerw//z9//////////////////// + //////////////////////////////////v8/+/z/+Dm+/D0//z9//////////7+//j6/9Pd+UhLjb/H + 9/D0//3+//n7/+nt/+jt//n7//////////////////////////////////////////////////////// + //7///7+//7+//7+//////////r8/+7z/83W+ImU2A0UdFNarr/K9env//X4//z9//3+//7///////// + //////////////////////////////////////////////////////////////////7///j6/+Pq/255 + xhckjE5XsVVftUlTqwAKeTA9nr3H8+7z//v8//////////////////////////////////////////// + //////////////////////////////7+//b4/9Tc+Sc0mRonj8rV/crX/ZSb48rX/brG8wwWgQAEdJei + 4efu//n7//7+//z9//z9//z9//z9//3+//////////////////////////////3+//f5/+3y/+nv/+ft + /8vV+io2mImU2M7c/7vG9yIvlQAOfCg4mM3Y/s/c/4aR1AQRfGtzwtni/ebt/9vi/tri/tXd+9Tc+O3x + /vz9//////////////////////////n6/87V+FVftkRPrFlnvSEqjQoUfmJvwWFvvg0TfQQIcxEchwAD + cy89n19rvVVitQwZgwAAaiMrkT9NqTVBoiw3mhQihig1mNLX+fv8//////////////////////////b5 + /52l4EFLqoCK03yF0VBctGhyw52o5GVrvQAAaneBzsHM+jA3mhYgiTtIpJOf3ouW2AAAbmh0wbbA8bS+ + 7qiz5pCb16+56e/z//3+//////////////////////////v8//H1/+vw/+zx/+nv/7/J9YqP3MbP/8LM + +hwqkFZftaCp5EhRrcTQ+9jj/8rW/UJMqn6J0ebt//X3//f5//b4//X3//f5//z9//////////////// + //////////7+//z9//3+//////////3+/+7z/6at64iP3aWs7XN8zRIfhyUykp2o5MHM+oKM0xonjY6X + 2+jv//v8//////7+//n7//b5//r7//7///////////////////7+//f5/+rw/9Pa9fL0/v7///////// + //v8//H1/+Tr/7i/91liu0NPq0VQrS06m0NNqDdCoYqU1+nv//v8//////////n7/9zi/qSt59ri/fL1 + //v8//7///////z9//D0/8rT+h0sjkVQrPD0//////////////////////z9/+7z/8LL9Jqk4aGq6LW/ + 8c3W9+Xs/vH1//v8//////////////f5/6at5gAAbxIfh6u16+Po/fr7//////b5/6ev5gAIeAAPernC + 8fX4//////////3+//v8//z9//////3+//j6//P3//P2//b4//r8//7+//7+//v8//r8//3+//////v8 + /+Xr/nuIzwAAbBseg5Sb2fb5//////f5/8DF8pWe3d/n/vT3//39//////v8/+zx/87V9+3x/v3+//// + //3+//j6//X4//v8//////////n7/+Dm/snR9fD0//39//z8/fv8/+3y/8LK9aGq4dfd9/n7//////z9 + //b5//X4//v8//////////7+/+7z/4aP1gEPet7k/f39//////f5/83U+ZCZ2u3x/v7+//////P3/215 + wgAJd7fB8/L1//7+//////3+//j6//f5//r8//7+//////////////////////////////j6/87W/AAA + X2duue3y//7+//////D0/05asBQfidzj/P39//////X4/6Su6AAAXBccgtff/vv8//////////////// + //////////////////////////////////////P3/3F8xhYli9Xe/fn6/////////+3y/1pltQAJd9be + /fv8//////z9/+rw/36I0Bknjs/W+vv8//////////////////////////////////////////////// + //////f5/8HI7tnf+/X4//7+/////////+/0/3R7xgAAb9ng/Pz9//////////n7/+Ln/dLY+fP2//3+ + //////////////////////////////////////////////////////3+//r7//v8//7+//////////// + //b4/7/F84eP0e/0//7+//////////7+//z9//v8//3+//////////////////////////////////// + //////////////////////////////////////////////////z9//b5//X4//v8//////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////w////4 + P///+D////g8//D4MH/geCB/4Dggf+A4IH/wOCD/+DAB//hgAf//gAP//wAAB/AAAAPwAAAD8AAAA/AA + AAfjAAEHgYADAQPgBwEDEAEBAghgAQwIIEH8CCB//Bggf/wYMH/8ODD///h/////////////KAAAABAA + AAAgAAAAAQAYAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///+vv/fL1/v///wAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///4+Vx7/F5v///wAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAP///4CHtrS62////////////////////wAAAAAAAAAAAP////H0/vf6/v// + /////////4yTwrrB4f///+zw+7rA6P39/////wAAAAAAAAAAAP///56l2BkcguXr/P///////42Uw8jO + 6P///ysvjWVqtP///////wAAAAAAAAAAAP////D0/0hPpsDG6////////6y02d7k8////3qAx+/z/f// + /wAAAAAAAAAAAAAAAAAAAP///////////////8zT8V5ns1Rcrdzh9f///////////wAAAAAAAAAAAAAA + AAAAAP////////7+/6ix3nmBxFthtmdwu09WqbC54/v9//r8//j6//39/wAAAAAAAAAAAOjt/H6I0FJc + skpSqHF+wRMahFZhs4iT1AsNc1pgrm52v2RsuO/z/gAAAP////////L2/cLJ7rrD64+V4DY+ozU+mYmU + 0X2Hy1hfss7V8urv/PP2/v///wAAAP///+Pp+d/k9////////+Pp/4uR3ysymW14xYOM0fD0/P///+Xq + +ri/6Pj6/wAAAOrv/j5DnbS75P////////////X4/+/0/ubr+/r7/////////9rh+hgZhKGo2QAAAPDz + /eLn+f////j6/2Nqttrg9////+Hn+P3+//3+/1hescLJ6/////L2/eru/AAAAAAAAAAAAP///8rR70tR + p/3+//v8/zY6jNPY7////09WqWpwu////wAAAAAAAAAAAAAAAAAAAAAAAPb4/vr7//////v8/5Wd1eHm + +P////v8//T3/wAAAAAAAAAAAAAAAP//AAD8PwAA/D8AAPwDAACAAwAAgAMAAIAHAADABwAAwAEAAMAB + AAAAAQAAAAEAAAABAAAAAQAAwAcAAOAPAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////v7//f7//P3//P3//P3/ + /f7//v7///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////v7//P3/ + +fv/+fv/+Pr/+fv/+vv//P3//v////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////f7/+fr/8/b/7PL/5+3/6e/+9Pf/+vv//v7///////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////P3/9/r/6O7/cXe1UVaet7z17fL/+Pr//f3///////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////+/z/9Pj/4Oj/NzyCUlOd2dz/6O//9Pf//P3///// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////+vv/8vb/2+P9X2OmREGLnqPd + 4+v/8vb/+/z///////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////+vv/8fb/ + 1N35bXK1JSRtbHGz5O7/8fX/+/z///////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////+vv/8PX/3Ob/U1eaDwtXjZLT4+z/8fX/+/z///////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////+vv/8fb/2eP+MjR6AAA+c3i34Or/8fX/+/z///////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////+vv/8vb/1d/7MS91AAA1UFSS4On/8vb/+/z///// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////+vv/8fb/2OL+NjZ7AAArX2Ok + 4uz/8fX/+/z///////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////+vv/8fb/ + 2eP/LjJ1DAxKfYTE4Or/8fX/+/z//////////////////////////////v7//v7//f7//f7//v7//v// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////+vv/8PX/3OX/gILIR0eVeoHC3eb/8fX/+/z//////////////////////v7//P3/+fv/+Pr/ + +Pr/+Pr/+vv//P3//v7///////////////////////////////////////////////////////////// + /////////////////////////////v7//f7//P3/+vv/+vv/+/z//f3//v7///////////////////// + ////////////////////////+vv/8PX/2eP9ZWeqHx1obnOz4Or/8fX/+/z//////////////////v7/ + +/z/9fj/8vb/8PX/7vT/8fb/9fj/+fr//f7///////////////////////////////////////////// + /////////////////////////////////////////v///P3/+Pr/9fj/9fj/9Pj/9Pf/9vn/+/z//v7/ + ////////////////////////////////////////+vv/8fb/2eP9ODp9AAA5jZDQ5O7/8PX/+/z///// + /////////v7/+/z/9Pf/7fP/5u//wsz6j5XfuMDx7fL/9vn//P3///////////////////////////// + /////////////////////////////////////////////////////////f7/+Pr/8/b/5+3/2eH/2uP/ + 5u3/7fP/8/b/+vv//f7/////////////////////////////////////+vv/8PX/3ef/U1ebBgVKio/O + 4uz/8fX/+/z//////////v///P3/9fj/7fP/4uv/hIzZHSWPAABmU1i14ub/9/r/+/z///////////// + /////////////////////////////////////////////////////////////////////////P3/9Pf/ + 7/X/09z/TlSzNzWYj5bh5O7/6/L/8vb/+fv//f7/////////////////////////////////+vv/8fX/ + 2eP/QUWIEhBZbnSz3uj/8fb/+/z//////////f7/+Pr/7/T/6PH/iI7cAABvAABqAABncXjK6O//9fj/ + +/z///////////////////////////////////////////////////////////////////////////// + ////////+/z/8/f/2uD/Z27EAABnAABiBgl4jJTd5vD/6O//8vX/+fv//f7///////////////////// + ////////+vv/8fb/2OP/Mjd6AQE6ZGup4er/8fX/+/z/////////+vz/8fX/6/T/xM/8ExyJAABwAABu + GySRxc387fT/9ff//P3///////////////////////////////////////////////////////////// + ////////////////////////+vz/8/f/1Nr/MzqhAABhAxOBAARyBgp5jpLg5Oz/7PP/9Pf/+vz//v7/ + ////////////////////////+vv/8fb/2eP/KCtvBwZOjJHS4Or/8fX/+/z//////f7/9/n/7fP/3+j/ + UFq3AABtAAZ3BAh6mZ/n5vD/7vP/+Pr//v7///////////////////////////////////////////// + ////////////////////////////////////////+/z/9Pj/6e//sbb1KzWcAABwBhaBAAFyAgp6fITR + 1d777/T/+Pr//f7/////////////////////////+vv/8PX/3+j/WF2hBglTnaTj5O3/8PX/+/z///// + /P3/9Pf/6vL/k5riAAByAAR0AABrY2vE4ur/6vH/9ff//P3///////////////////////////////// + /////////////////////////////////////////////////////////f3/9/n/7fL/5O3/ytX/RU6w + AABpAA5+AABuAABnhord6e7/+fv//f7/////////////////////////+vv/7/T/3+j/k5jbT1KdgYjJ + 3uf+8fX/+/z/////+/z/9fn/4ef/NDqhAABnAABrJjCU0Nn/5/D/8fX/+vv//v7///////////////// + /////////////////////////////////////////////////////////////////////////v7/+/z/ + 9vn/7vP/6vP/ztb/O0CmAABpAABrQkuoxMn57PH/+Pr//f7/////////////////////////+vv/8PX/ + 2+X/en/CUFGak5nY3+j/8fX//P3//////P3/9fj/4en/i5DbNT2hIyuTpqzv4uz/7vP/9/n//f7///// + //////////////////////////////////////////////////////////////////////////////// + /////////////v7//P3/9vn/7/P/6vL/ytH/X2i9XWi7wsf/6e//8/f/+Pr//v7///////////////// + ////////+vv/8PX/3OX/WF2hW1ylvMD+3uf/8PX/+/z//////f7/9vn/7fP/4uj/j5Pgf4LV3+X/6fD/ + 9Pf//P3///////////////////////////////////////////////////////////////////////// + /////////////////////////////////v///P3/+Pr/8vX/7fP/5+//5u7/6vD/8PT/9vn//P3//v7/ + /////////////////////f7/9/n/7fP/0tz9LDJzNjh/nqTk2uT/7fL/9/n//f7//f7/+fv/8/b/7PL/ + 3eX/zM//5ev/9fj/+fv//v7///////////////////////////////////////////////////////// + /////////////////////////////////////////////////////v///f3/+vv/9/n/9vn/9fj/9vn/ + +fr//P3//v7//////////////v///f7/+vv/9vn/7/T/5vD/2Ob/VFubERNdoajk4u//5O7/7vP/9vj/ + +fr/+vv/+Pr/9fj/9Pj/9fj/9fj/+Pr//P3///////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////v///v7/ + /f7//P3//P3//f3//v7//v///////////////f7/+vz/9vn/8fX/7vT/5O3/3eb/z9n/cHjICxN5d37L + z9n/2eP/5O3/6/L/8PT/9Pf/9/n/+vv/+vv/+/z//P3//f3//v7///////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////P3/+Pr/8/b/7vT/6vL/z9r+jZjeQUeq + IiuQCBN3AAFrBRB8Nj2iUViym6XlydH/4+z/6/L/8PT/9/n/+/z//f7//v////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////f3/9/n/8fX/6/L/3uf/ + mKTkLzibAABoAAB0Fx+HDBh7FSGDAg16AABYAABlCBB/Ji2UhYza1+D/6PL/7fL/9Pf/+vv//f7///// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////v7//P3/9/n/ + 8PT/7PT/z9j/XmO+AABtAABcMDSXoajsu8X7VV+5hYzblZ/fTVSxFSKMAABkAABnAAN2Qkmpsbrz5e3/ + 6vH/8fX/+Pr//P3//v////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////P3/9/n/8PX/7PT/vcn3LTOZAABaAgR1ZWzD0Nf/5vL/1OP/l53lzs3/6fP/4+7/sLzwZ23CBxSD + AABnAABlHiaSmqHo3+j/5+//7/T/9vn//P3//v7///////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////v7/ + /v7//v7//v7//f7/+/z/9vj/7vP/7PX/tcLzEBeGAABkPEWlqLPt2eX/4e7/3On/uMX1gofVe3vPhYzY + z93+5/X/4e3/lJ3gHiOPAABtAABqChiEbHLIytD/5/D/7PL/8/f/+Pr/+fr/+Pr/+Pr/+Pr/+Pr/+Pr/ + +Pr/+fv/+vv/+/z//f7//v7///////////////////////////////////////////////////////// + /v7//f7/+/z/+fv/9/n/9vj/9fj/9Pf/8fX/7PL/4uv/l6HgDhF7AAN4iZDe0d7/3uz/4vD/w83/VVm3 + ICiSAAFyAABlAABwaHTD1N//2un/3er/w838ZW3BEyOJJzKVAQ16NDmfwsn75fD/5u7/7PL/7vP/7fP/ + 7fP/7fL/7fP/7vP/7/T/8fb/9Pj/9vn/+fr//f3//v////////////////////////////////////// + /////////////v7//P3/+Pr/9Pf/8fX/7vT/7PL/6/L/6fH/5u7/6vX/tsD0CQx4AAFwkZvi7ff/4vD/ + 4fD/z9j/OkGlAABiAABwBxWAAAt7BBN+P0uofYLUztb/4O7/6fb/6fP/qa7xQkyoBg56AABqMjugx8/+ + 5fH/4Ov/4On/3uj/3eb/3+j/3uj/1+L/0d3/1d7/3+f/7fL/9vj/+vz//v7///////////////////// + /////////////////////////////f7/+fr/8/f/6/L/2d//v8j6vcf5ucP1wMv8wM3+vMj6PkqoAABo + UF25usP7tsPyvsr6sLrwQ0utAABqAAV1OUameIDRKDWZAAd2GyeOLDecmaHntsL0pbLom6riq7LzUlu0 + AANzBhR/AAZ0NT+ja3bBY2i/XGG6UViyWl65XGG7XGC6TVWvQU6pPkalODygqK7p8vb/+vz//v7///// + /////////////////////////////////////////////P3/9/n/7/T/wcj2R0ysExeFERmGDxuIFB6K + FBqICxSEAABsAAByDBiDCRSBBRCADhaFCRODAAh4AxF/AAl4CxeDHSaPAAp6AAN0AA19AAd3CBOBEBqH + BhGBAAh5AABwAAByAAh5BhSCAxWCAABsAABvAABlAABnAABxAABjAABmAABhAABdAABYAABhCAt/q7Lr + 8/f/+vv//v7//////////////////////////////////////////////////P3/+fv/3uT/SE2vAABn + CBB/GiCMLzmfLTWcGByJFRyKGCOOMj2gHymRDxiGGyOPLDCXBRF/AAh3BhaCEyKMICqTKC2WNDqfIzCV + Awx6Eh+JHiaPAAR3AAZ5CxSDICWQX2q7Q1CqAA1+AAFxDxuHiZTbVGC4dHnQnabrTVqzY23EUV62Slau + LjaZXWm9sLjz5ez/9vn/+fv//v7//////////////////////////////////////////////////P3/ + +Pv/4+n+e4LPfoPVpqv2vsf/zNX/zdb/xtH/v8v8pK7spKfysLb3vcr4ws784ej/hI/YAAZ1AAJzVF25 + yM//3Of/5+//i5LcAABpMzyfp6vxoKznlqHhqbbtx9H/8fz/kpvfAABiAABph4zc5PD/2OP/193/3un/ + 1+D/2OH/1+D/0Nr/zNL/3+j/6/L/7/T/9vn//P3//v////////////////////////////////////// + /////////////f7/+Pr/9Pf/6vD/5u3/3+b/4uv/6PD/5+//5O3/5/P/sL3sXmS7mZzoz9f/3+z/4e// + mKLiEiKKCBF/KTWZr7T06/f/3ev/VF2zChSBipPcz9v+4u7/3ur/3ev/5/X/qrPrISmSDRJ2Xmq/3ur/ + 4uv/6vH/7fP/7fL/7/T/7vP/7fP/7fP/8PX/8fX/9Pf/+Pr/+/z//v7///////////////////////// + /////////////////////////////v7//P3/+Pr/9vn/9Pf/8vb/8vb/8/b/9Pf/7/T/6/L/tL/ubXLH + en/Ti43gqavy0t3/nafjMj6fJzaaAAV1GyeOYmW7Nz6fAABgNj6i1N//3uz/2uX/3Oj/5PH/wcj7FR2J + AAN0gong0tr/6fH/7/P/9vj/+Pr/+fv/+fv/+Pr/+Pr/+Pr/+fv/+vv//P3//f7//v////////////// + /////////////////////////////////////////////////v7//f7//P3/+/z/+/z/+/z//f3//f7/ + +fv/8fX/5Oz/jpbfc3jObnXLcXfOk5rks7b4iY3dR1KvDhuEAABoAABlEBV9U12ytcD13Or/3en/3ej/ + 1eL/q7fvGR+MKDKZbnnNxc/76PD/8fX/+fr//f7//v///////v7//f7//f3//P3//f3//f7//v////// + /////////////////////////////////////////////////////v7//f7//P3//P3//f7//v7///// + /////////////////f7/9vn/7/T/yNH5lJrleoDVmZ3pmpzpc3nPfoTWf4bYVFy3HSaLZ3PGsrb8v8r8 + y9n9q7jre4LRf4fUgIvXAwZ1AABrhYjb0NX/6PH/8PX/+Pr//f7//////////v///f3/+vv/+Pr/9/r/ + 9/n/+Pr/+/z//f7//v7//////////////////////////////////////v///f7/+/z/+fr/9vj/9/n/ + +vz/+vv/+/z//v7//////////////////v7/+vz/8/f/7PL/2uT/t8H1srP6vcH+nKTnSlOxV2C7TVaz + WGS8QUqmSlSuSFOtR1GtbXTKVl23ARB5AAh2AABnd33P3eP/4ur/7/T/9/n//P3//////////////P3/ + 9/n/8vb/7PH/6fD/7PL/7vP/8vb/9vn/+/z//f7//////////////////////////////v7/+/z/+Pr/ + 8/b/7/T/8Pb/6vH/3eP97vL++fr//P3//////////////////////f7/+vv/9fj/7/T/5+//z9f+t7v4 + uLn9Z2zFLzucFCGIMz6gGCCMAAd4AAl2Dx2EER+GXWK8c3XLKzKXd4LP4er/6/L/8PX/9/n//P3//v// + /////////v7/+fv/8/b/7PP/y9H/i4/erLbt4er/5e3/7fP/8/b/+fv//f3//v7///////////////// + /v7/+/z/9vj/8PT/6/L/3+n/x9H9aHTAZGvG3+b9+Pr/+/z//////////////////////////v7/+/z/ + +Pr/8vb/6/H/3OX+wMn4maDmdHrPWGG6T1a1eoHWcHfOTlayUlq1SlKubHjAxMj/0dn/4+v/7PL/8vb/ + +Pr//P3//v7//////////////f7/+fr/7vP/xsv5YGXAHymRKjKYYWS9rbLz4u3/6/P/8vb/+fr//f7/ + /////////////v//+/z/9vj/7fL/5e3/xs7/Y23BIiiSAABeLTab3+b/9/r/+/z///////////////// + /////////////////f7/+vz/9vj/8PX/6vH/3eb/ydL8xM/6uMPyt733w8j/zNb/1Nz/3OT/4uz/5u7/ + 7fP/8vb/9vj/+vz//f7//////////////////////f7/+fv/7vP/jpHiAAJ1CxaBER6GAABoFRmGbXbH + 0Nf/7PL/9fj//P3//////////////v7/+fv/8/f/4Of/hYvbKDGZAABuAABdAAZyi5La5+7/9vn/+/z/ + /////////////////////////////////////v7//P3/+fv/9ff/8vb/7/X/7fP/6/L/5u3/5ez/6fD/ + 7PP/7/T/8fX/9Pf/9/n/+vv//P3//v7//v///////////////////////v7/+fv/8fb/2eH9fIbQExqH + AABrAAp6AAFyAABwS0+uztX39vn/+vz//////////////f7/+Pr/8ff/qbLpAABrAABhAABwDBWAfobX + 5e3/8PX/9vn//f3//////////v///f7/+/z/+vv/+vv/+vz//P3//v7//v///v7//P3/+vz/+Pr/9/n/ + 9vj/9vj/9vj/9vj/9/n/+fr/+/z//P3//f7//v7//f7//P3/+/z/+vz/+/z//P3//v7//////v7/+/z/ + 9fj/7/T/5/H/uML1U1e1AAh5AABuAABvMjmdv8bz9vr/+vv//////////////f7/+fv/7/T/iY7aDxSA + GiONa3XHsr7w4Oj/6/H/9Pf/+vz//v7//////v///P3/+Pr/9Pf/8/f/9fj/9fj/9vn/+/z//v7///// + /////////v7//f7//P3/+/z/+/z//P3//f7//v///////////////v7/+/z/9/n/9vn/9vn/9Pj/9vn/ + +/z//v7//////f7/+vz/9fj/7/T/6vL/3ef/i5PbGRqJBQl5jJbZ6vH/9Pj/+/z//////////////f7/ + +fv/8fT/1Nn9t7/0wcr54er/7fT/8fX/9fj/+vv//f7//////////f3/+Pr/8PT/6/L/3uX/ztb/5Or/ + 8/f/+Pr//f7//////////////f7/+vz/+Pr/+fv/+fv/+vv//f3//v///////////////P3/9/n/7vL/ + 193/ztf/5u3/7vP/9Pf/+/z//v7//////v7//P3/+Pr/8fX/7PP/5/D/sLfxoKnk4+r/8vf/9/n//f3/ + /////////////v7/+/z/9vn/9Pf/8vb/8fb/8fX/9Pf/+Pr//P3//v7//////////v7/+vv/8vb/5+7/ + y9H/WWO9KSmSkZXj6vD/+Pv//P3//////////f7/+Pr/9fj/8vb/6O7/7vP/9fj/+Pr//f7///////// + /v//+vv/8vb/7PP/hYraKiqKlp7i6PD/7fP/9ff/+/z//v7//////////f7/+vv/9ff/8fX/8PX/8vb/ + 8/f/9vn/+/z//v7//////////////////f7/+/z/+vv/+fr/+fr/+vv//P3//v7///////////////// + /P3/9fj/7PL/1d7/RUysAABhAABlg4ja6/D/+Pr//P3/////////+/z/9fj/6e7/2eD/h4/bnaXg7PH/ + 9fj/+/z//////////v7/+Pr/8PX/y9X1JDGVAABaERWDoKnp6PH/7vP/9/n//P3//////////////v7/ + /P3/+vv/+fv/+fv/+vv//P3//v7//////////////////////////v7//v7//v7//v7//v////////// + /////////////v7/+fv/8PX/7PX/ipPdAABsAABlQ1Cp3Ob/7vP/9/n//f7/////////+fv/9Pj/yNH5 + Ule2DBJ8Ljie0df+8fb/+fv//v7//////v7/+Pr/7/X/hY3YAABxAAl7AABuEBaEs7nz6fH/8fX/+vv/ + /v7//////////////////v///v7//v7//v7///////////////////////////////////////////// + /////////////////////////////f3/9vn/7PL/0tn/LzidAQFsAAB0iZHb6vP/8PT/+fv//v////// + /v7/+Pr/8vf/r7rqAAV4AABdPUen1N//7PL/9vn//f7//////v7/+fr/7/T/yc75S1G0AABrARKAAABp + Qker0df/7fP/9/n//f7///////////////////////////////////////////////////////////// + /////////////////////////////////////////////P3/9/n/5+7/cXXNAAd2AABuMDebzdT97PL/ + 9vj//P3//////////v7/9/n/7/X/tL/uFCCLAABqHSqRvcf46fD/9Pf//f3/////////+vv/8vX/6vH/ + yM3+JC2XAABtAAV2Agx9q7Ly7vT/9vn//f7///////////////////////////////////////////// + /////////////////////////////////////////////////////////////P3/9/r/4uj/WWO1AAVx + KTaYu8T07fT/8vb/+vv//v7//////////v7/9/n/7vX/vsn1Iy2SAABrAQ99mp/o6PD/9Pf//P3///// + /////P3/9/n/7vP/6fL/s7z2DBB/AABeQ0uttrr56e7/+Pr//f7///////////////////////////// + /////////////////////////////////////////////////////////////////////////////P3/ + +fv/4ef6g4zNbXfFw8v27fT/8vb/+Pr//f3//////////////v7/9/n/7vT/yNL7MjucAABtBxF/nKLo + 6fH/9Pf//P3//////////v7/+/z/9fj/7fL/6/T/jZXbLzScrrP14en/7fL/+fv//v7///////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////f7/+vz/8PP91dr34+f/8vb/8/f/9/r//P3//v///////////////v7/+Pr/8PX/1N3/ + QUqmAQRxBQ98m6Dm7PL/9fj//P3//////////////v7/+/z/9ff/8PX/5ez/ytH94ej/8vb/9vj/+/z/ + /v7///////////////////////////////////////////////////////////////////////////// + /////////////////////////////v7//P3/+vz/+fv/+Pr/+Pr/+vv//f3//v////////////////// + /v//+fv/9Pf/2+L/SVGtAABsLTaZytL58fX/9/n//f7//////////////////v7/+/z/9/n/9fj/9vn/ + 9fj/9vj/+vz//f7///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////v7//f7//f3//f3//f3//v7//v////// + ////////////////////+/z/9vn/6e//mZ7gTVarr7bp6/H/9fj/+vv//v7///////////////////// + /v7//f7/+/z/+/z/+/z//P3//v7///////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////f3/+Pr/9fj/6e7/4+n/8fb/9Pf/+Pr//f3///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////v7//P3/+fv/+fv/+vv/+Pr/+vv/ + /P3//v7///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////v7//f7/ + /f3//P3//f7//v7//v////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////4D/////////AH////////8Af////////wB/////////AH////////8Af////////wB/////// + //AH////////8Af////////wB/////////AH////////8AfwP//////wB8Af//+Af/AHgB///wA/8AcA + H///AB/wBgAf//8AD/AGAB///wAH8AYAH///AAPwBAAf//8AA/AEAD///wAD8AQAP///AAPwBAB///+A + A/AEAP///8AD4AAA////4AcAAAH////wDgAAAf/////8AAAH//////gAAAf/////4AAAAf/////gAAAA + ////+AAAAAAAD//AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+A + AAAAAAAP/4AAAAAAAB//wAAAAABAf/4HwAAAAYAf8APAAAADgA/gA+AAAAMAA8AD8AAABwADgAP8AAAf + AAOAA/4AAB8AA4ADAAAAAQADgAIAcA4AgAOABgBwDgBAA4AMAGAMADADwDwAYAwAOAfg+ABgBAAeH//4 + AEAEAB////gAwAYAH///+ADABgAf///4AcAGAB////gBwAcAH///+APAB4A////8B+AHwH//////4A// + ///////gD/////////Af//////////////8= + + + \ No newline at end of file diff --git a/CodeWalker/WorldForm.Designer.cs b/CodeWalker/WorldForm.Designer.cs index 42d8944..f5d3502 100644 --- a/CodeWalker/WorldForm.Designer.cs +++ b/CodeWalker/WorldForm.Designer.cs @@ -223,6 +223,7 @@ namespace CodeWalker this.ToolsMenuSelectionInfo = new System.Windows.Forms.ToolStripMenuItem(); this.ToolsMenuProjectWindow = new System.Windows.Forms.ToolStripMenuItem(); this.ToolsMenuCutsceneViewer = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolsMenuAudioExplorer = new System.Windows.Forms.ToolStripMenuItem(); this.ToolsMenuWorldSearch = new System.Windows.Forms.ToolStripMenuItem(); this.ToolsMenuBinarySearch = new System.Windows.Forms.ToolStripMenuItem(); this.ToolsMenuJenkGen = new System.Windows.Forms.ToolStripMenuItem(); @@ -310,7 +311,6 @@ namespace CodeWalker this.ToolbarPanel = new System.Windows.Forms.Panel(); this.SubtitleLabel = new System.Windows.Forms.Label(); this.SubtitleTimer = new System.Windows.Forms.Timer(this.components); - this.ToolsMenuAudioExplorer = new System.Windows.Forms.ToolStripMenuItem(); this.StatusStrip.SuspendLayout(); this.ToolsPanel.SuspendLayout(); this.ToolsTabControl.SuspendLayout(); @@ -2762,12 +2762,12 @@ namespace CodeWalker this.ToolsMenuExtractShaders, this.ToolsMenuOptions}); this.ToolsMenu.Name = "ToolsMenu"; - this.ToolsMenu.Size = new System.Drawing.Size(181, 356); + this.ToolsMenu.Size = new System.Drawing.Size(170, 334); // // ToolsMenuRPFBrowser // this.ToolsMenuRPFBrowser.Name = "ToolsMenuRPFBrowser"; - this.ToolsMenuRPFBrowser.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuRPFBrowser.Size = new System.Drawing.Size(169, 22); this.ToolsMenuRPFBrowser.Text = "RPF Browser..."; this.ToolsMenuRPFBrowser.Visible = false; this.ToolsMenuRPFBrowser.Click += new System.EventHandler(this.ToolsMenuRPFBrowser_Click); @@ -2775,14 +2775,14 @@ namespace CodeWalker // ToolsMenuRPFExplorer // this.ToolsMenuRPFExplorer.Name = "ToolsMenuRPFExplorer"; - this.ToolsMenuRPFExplorer.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuRPFExplorer.Size = new System.Drawing.Size(169, 22); this.ToolsMenuRPFExplorer.Text = "RPF Explorer..."; this.ToolsMenuRPFExplorer.Click += new System.EventHandler(this.ToolsMenuRPFExplorer_Click); // // ToolsMenuSelectionInfo // this.ToolsMenuSelectionInfo.Name = "ToolsMenuSelectionInfo"; - this.ToolsMenuSelectionInfo.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuSelectionInfo.Size = new System.Drawing.Size(169, 22); this.ToolsMenuSelectionInfo.Text = "Selection info..."; this.ToolsMenuSelectionInfo.Click += new System.EventHandler(this.ToolsMenuSelectionInfo_Click); // @@ -2790,7 +2790,7 @@ namespace CodeWalker // this.ToolsMenuProjectWindow.Enabled = false; this.ToolsMenuProjectWindow.Name = "ToolsMenuProjectWindow"; - this.ToolsMenuProjectWindow.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuProjectWindow.Size = new System.Drawing.Size(169, 22); this.ToolsMenuProjectWindow.Text = "Project window..."; this.ToolsMenuProjectWindow.Click += new System.EventHandler(this.ToolsMenuProjectWindow_Click); // @@ -2798,14 +2798,22 @@ namespace CodeWalker // this.ToolsMenuCutsceneViewer.Enabled = false; this.ToolsMenuCutsceneViewer.Name = "ToolsMenuCutsceneViewer"; - this.ToolsMenuCutsceneViewer.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuCutsceneViewer.Size = new System.Drawing.Size(169, 22); this.ToolsMenuCutsceneViewer.Text = "Cutscene viewer..."; this.ToolsMenuCutsceneViewer.Click += new System.EventHandler(this.ToolsMenuCutsceneViewer_Click); // + // ToolsMenuAudioExplorer + // + this.ToolsMenuAudioExplorer.Enabled = false; + this.ToolsMenuAudioExplorer.Name = "ToolsMenuAudioExplorer"; + this.ToolsMenuAudioExplorer.Size = new System.Drawing.Size(169, 22); + this.ToolsMenuAudioExplorer.Text = "Audio explorer..."; + this.ToolsMenuAudioExplorer.Click += new System.EventHandler(this.ToolsMenuAudioExplorer_Click); + // // ToolsMenuWorldSearch // this.ToolsMenuWorldSearch.Name = "ToolsMenuWorldSearch"; - this.ToolsMenuWorldSearch.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuWorldSearch.Size = new System.Drawing.Size(169, 22); this.ToolsMenuWorldSearch.Text = "World search..."; this.ToolsMenuWorldSearch.Click += new System.EventHandler(this.ToolsMenuWorldSearch_Click); // @@ -2813,14 +2821,14 @@ namespace CodeWalker // this.ToolsMenuBinarySearch.Enabled = false; this.ToolsMenuBinarySearch.Name = "ToolsMenuBinarySearch"; - this.ToolsMenuBinarySearch.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuBinarySearch.Size = new System.Drawing.Size(169, 22); this.ToolsMenuBinarySearch.Text = "Binary search..."; this.ToolsMenuBinarySearch.Click += new System.EventHandler(this.ToolsMenuBinarySearch_Click); // // ToolsMenuJenkGen // this.ToolsMenuJenkGen.Name = "ToolsMenuJenkGen"; - this.ToolsMenuJenkGen.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuJenkGen.Size = new System.Drawing.Size(169, 22); this.ToolsMenuJenkGen.Text = "JenkGen..."; this.ToolsMenuJenkGen.Click += new System.EventHandler(this.ToolsMenuJenkGen_Click); // @@ -2828,42 +2836,42 @@ namespace CodeWalker // this.ToolsMenuJenkInd.Enabled = false; this.ToolsMenuJenkInd.Name = "ToolsMenuJenkInd"; - this.ToolsMenuJenkInd.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuJenkInd.Size = new System.Drawing.Size(169, 22); this.ToolsMenuJenkInd.Text = "JenkInd..."; this.ToolsMenuJenkInd.Click += new System.EventHandler(this.ToolsMenuJenkInd_Click); // // ToolsMenuExtractScripts // this.ToolsMenuExtractScripts.Name = "ToolsMenuExtractScripts"; - this.ToolsMenuExtractScripts.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuExtractScripts.Size = new System.Drawing.Size(169, 22); this.ToolsMenuExtractScripts.Text = "Extract scripts..."; this.ToolsMenuExtractScripts.Click += new System.EventHandler(this.ToolsMenuExtractScripts_Click); // // ToolsMenuExtractTextures // this.ToolsMenuExtractTextures.Name = "ToolsMenuExtractTextures"; - this.ToolsMenuExtractTextures.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuExtractTextures.Size = new System.Drawing.Size(169, 22); this.ToolsMenuExtractTextures.Text = "Extract textures..."; this.ToolsMenuExtractTextures.Click += new System.EventHandler(this.ToolsMenuExtractTextures_Click); // // ToolsMenuExtractRawFiles // this.ToolsMenuExtractRawFiles.Name = "ToolsMenuExtractRawFiles"; - this.ToolsMenuExtractRawFiles.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuExtractRawFiles.Size = new System.Drawing.Size(169, 22); this.ToolsMenuExtractRawFiles.Text = "Extract raw files..."; this.ToolsMenuExtractRawFiles.Click += new System.EventHandler(this.ToolsMenuExtractRawFiles_Click); // // ToolsMenuExtractShaders // this.ToolsMenuExtractShaders.Name = "ToolsMenuExtractShaders"; - this.ToolsMenuExtractShaders.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuExtractShaders.Size = new System.Drawing.Size(169, 22); this.ToolsMenuExtractShaders.Text = "Extract shaders..."; this.ToolsMenuExtractShaders.Click += new System.EventHandler(this.ToolsMenuExtractShaders_Click); // // ToolsMenuOptions // this.ToolsMenuOptions.Name = "ToolsMenuOptions"; - this.ToolsMenuOptions.Size = new System.Drawing.Size(180, 22); + this.ToolsMenuOptions.Size = new System.Drawing.Size(169, 22); this.ToolsMenuOptions.Text = "Options..."; this.ToolsMenuOptions.Click += new System.EventHandler(this.ToolsMenuOptions_Click); // @@ -3590,14 +3598,6 @@ namespace CodeWalker // this.SubtitleTimer.Tick += new System.EventHandler(this.SubtitleTimer_Tick); // - // ToolsMenuAudioExplorer - // - this.ToolsMenuAudioExplorer.Enabled = false; - this.ToolsMenuAudioExplorer.Name = "ToolsMenuAudioExplorer"; - this.ToolsMenuAudioExplorer.Size = new System.Drawing.Size(180, 22); - this.ToolsMenuAudioExplorer.Text = "Audio explorer..."; - this.ToolsMenuAudioExplorer.Click += new System.EventHandler(this.ToolsMenuAudioExplorer_Click); - // // WorldForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -3617,6 +3617,7 @@ namespace CodeWalker this.Text = "CodeWalker"; this.Deactivate += new System.EventHandler(this.WorldForm_Deactivate); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.WorldForm_FormClosing); + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.WorldForm_FormClosed); this.Load += new System.EventHandler(this.WorldForm_Load); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.WorldForm_KeyDown); this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.WorldForm_KeyUp); diff --git a/CodeWalker/WorldForm.cs b/CodeWalker/WorldForm.cs index b8e1655..137d877 100644 --- a/CodeWalker/WorldForm.cs +++ b/CodeWalker/WorldForm.cs @@ -5939,6 +5939,11 @@ namespace CodeWalker { } + private void WorldForm_FormClosed(object sender, FormClosedEventArgs e) + { + SaveSettings(); + } + private void WorldForm_MouseDown(object sender, MouseEventArgs e) { switch (e.Button)