From 7bdf6a953f4eda67888f489dd7c521fecdfb0708 Mon Sep 17 00:00:00 2001 From: Caleb Anderson Date: Mon, 4 Oct 2010 02:30:04 -0500 Subject: [PATCH] New slider Range parameter. Palette modifications. Potential crash fix. Clamp function. Range parameter added to slider. Supports returning a range of values rather than just 0-1. Allows you to not have to post process the offset. Modified palette selector to not have full range, which was causing blown out units. Introduced exension method Clamp(min, max) Fixed crash deserializing out of bound color value using above extension. --- OpenRA.FileFormats/Exts.cs | 10 + OpenRA.FileFormats/FieldLoader.cs | 9 +- OpenRA.FileFormats/OpenRA.FileFormats.csproj | 2 +- OpenRA.Game/Exts.cs | 30 ++- OpenRA.Game/Server/Exts.cs | 11 + .../Widgets/Delegates/LobbyDelegate.cs | 202 +++++++++--------- OpenRA.Game/Widgets/SliderWidget.cs | 40 +++- mods/cnc/chrome/gamelobby.yaml | 3 + mods/ra/chrome/gamelobby.yaml | 3 + 9 files changed, 184 insertions(+), 126 deletions(-) mode change 100644 => 100755 OpenRA.FileFormats/Exts.cs mode change 100644 => 100755 OpenRA.FileFormats/FieldLoader.cs mode change 100644 => 100755 OpenRA.Game/Exts.cs mode change 100644 => 100755 OpenRA.Game/Server/Exts.cs mode change 100644 => 100755 OpenRA.Game/Widgets/Delegates/LobbyDelegate.cs mode change 100644 => 100755 OpenRA.Game/Widgets/SliderWidget.cs diff --git a/OpenRA.FileFormats/Exts.cs b/OpenRA.FileFormats/Exts.cs old mode 100644 new mode 100755 index 867c64489e..8ef0f7986f --- a/OpenRA.FileFormats/Exts.cs +++ b/OpenRA.FileFormats/Exts.cs @@ -85,5 +85,15 @@ namespace OpenRA { return (T[])mi.GetCustomAttributes( typeof( T ), true ); } + + public static T Clamp(this T val, T min, T max) where T : IComparable + { + if (val.CompareTo(min) < 0) + return min; + else if (val.CompareTo(max) > 0) + return max; + else + return val; + } } } diff --git a/OpenRA.FileFormats/FieldLoader.cs b/OpenRA.FileFormats/FieldLoader.cs old mode 100644 new mode 100755 index 94d7f35537..3e49e2d4a1 --- a/OpenRA.FileFormats/FieldLoader.cs +++ b/OpenRA.FileFormats/FieldLoader.cs @@ -112,9 +112,9 @@ namespace OpenRA.FileFormats { var parts = x.Split(','); if (parts.Length == 3) - return Color.FromArgb(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2])); + return Color.FromArgb(int.Parse(parts[0]).Clamp(0, 255), int.Parse(parts[1]).Clamp(0, 255), int.Parse(parts[2]).Clamp(0, 255)); if (parts.Length == 4) - return Color.FromArgb(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), int.Parse(parts[3])); + return Color.FromArgb(int.Parse(parts[0]).Clamp(0, 255), int.Parse(parts[1]).Clamp(0, 255), int.Parse(parts[2]).Clamp(0, 255), int.Parse(parts[3]).Clamp(0, 255)); return InvalidValueAction(x,fieldType, field); } @@ -264,7 +264,10 @@ namespace OpenRA.FileFormats if (f.FieldType == typeof(Color)) { var c = (Color)v; - return "{0},{1},{2},{3}".F(c.A,c.R,c.G,c.B); + return "{0},{1},{2},{3}".F(((int)c.A).Clamp(0, 255), + ((int)c.R).Clamp(0, 255), + ((int)c.G).Clamp(0, 255), + ((int)c.B).Clamp(0, 255)); } return f.FieldType.IsArray diff --git a/OpenRA.FileFormats/OpenRA.FileFormats.csproj b/OpenRA.FileFormats/OpenRA.FileFormats.csproj index 55a8bc8dbe..51d81a7bff 100644 --- a/OpenRA.FileFormats/OpenRA.FileFormats.csproj +++ b/OpenRA.FileFormats/OpenRA.FileFormats.csproj @@ -3,7 +3,7 @@ Debug AnyCPU - 9.0.30729 + 9.0.21022 2.0 {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA} Library diff --git a/OpenRA.Game/Exts.cs b/OpenRA.Game/Exts.cs old mode 100644 new mode 100755 index 55c5ae0eeb..d37669448a --- a/OpenRA.Game/Exts.cs +++ b/OpenRA.Game/Exts.cs @@ -34,17 +34,17 @@ namespace OpenRA return xs.Aggregate(1f, (a, x) => a * x); } - public static V GetOrAdd( this Dictionary d, K k ) + public static V GetOrAdd(this Dictionary d, K k) where V : new() { - return d.GetOrAdd( k, _ => new V() ); + return d.GetOrAdd(k, _ => new V()); } - public static V GetOrAdd( this Dictionary d, K k, Func createFn ) + public static V GetOrAdd(this Dictionary d, K k, Func createFn) { V ret; - if( !d.TryGetValue( k, out ret ) ) - d.Add( k, ret = createFn( k ) ); + if (!d.TryGetValue(k, out ret)) + d.Add(k, ret = createFn(k)); return ret; } @@ -54,18 +54,28 @@ namespace OpenRA return xs[r.Next(xs.Length)]; } - public static void DoTimed( this IEnumerable e, Action a, string text, double time ) + public static void DoTimed(this IEnumerable e, Action a, string text, double time) { var sw = new Stopwatch(); - e.Do( x => + e.Do(x => { var t = sw.ElapsedTime(); - a( x ); + a(x); var dt = sw.ElapsedTime() - t; - if( dt > time ) + if (dt > time) Log.Write("perf", text, x, dt * 1000, Game.LocalTick); - } ); + }); + } + + public static T Clamp(this T val, T min, T max) where T : IComparable + { + if (val.CompareTo(min) < 0) + return min; + else if (val.CompareTo(max) > 0) + return max; + else + return val; } } } diff --git a/OpenRA.Game/Server/Exts.cs b/OpenRA.Game/Server/Exts.cs old mode 100644 new mode 100755 index 7fecb5a158..bbc3099bf2 --- a/OpenRA.Game/Server/Exts.cs +++ b/OpenRA.Game/Server/Exts.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System; namespace OpenRA.Server { @@ -32,5 +33,15 @@ namespace OpenRA.Server { return ts.Except( new[] { t } ); } + + public static T Clamp(this T val, T min, T max) where T : IComparable + { + if (val.CompareTo(min) < 0) + return min; + else if (val.CompareTo(max) > 0) + return max; + else + return val; + } } } diff --git a/OpenRA.Game/Widgets/Delegates/LobbyDelegate.cs b/OpenRA.Game/Widgets/Delegates/LobbyDelegate.cs old mode 100644 new mode 100755 index 08f8f6ac4e..c14186573c --- a/OpenRA.Game/Widgets/Delegates/LobbyDelegate.cs +++ b/OpenRA.Game/Widgets/Delegates/LobbyDelegate.cs @@ -12,7 +12,7 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.FileFormats; -using OpenRA.Network; +using OpenRA.Network; namespace OpenRA.Widgets.Delegates { @@ -22,7 +22,7 @@ namespace OpenRA.Widgets.Delegates Dictionary CountryNames; string MapUid; - MapStub Map; + MapStub Map; public static Color CurrentColorPreview1; public static Color CurrentColorPreview2; @@ -133,74 +133,74 @@ namespace OpenRA.Widgets.Delegates teamChat ^= true; chatLabel.Text = (teamChat) ? "Team:" : "Chat:"; return true; - }; - - var colorChooser = lobby.GetWidget("COLOR_CHOOSER"); - var hueSlider = colorChooser.GetWidget("HUE_SLIDER"); - var satSlider = colorChooser.GetWidget("SAT_SLIDER"); - var lumSlider = colorChooser.GetWidget("LUM_SLIDER"); - var rangeSlider = colorChooser.GetWidget("RANGE_SLIDER"); - - hueSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); - satSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); - lumSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); - rangeSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); - - colorChooser.GetWidget("BUTTON_OK").OnMouseUp = mi => - { - colorChooser.IsVisible = () => false; - UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); - UpdatePlayerColor(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); - return true; }; - } - - void UpdatePlayerColor(float hf, float sf, float lf, float r) - { - var c1 = ColorFromHSL(hf, sf, lf); - var c2 = ColorFromHSL(hf, sf, r*lf); - - Game.Settings.Player.Color1 = c1; - Game.Settings.Player.Color2 = c2; - Game.Settings.Save(); - Game.IssueOrder(Order.Command("color {0},{1},{2},{3},{4},{5}".F(c1.R,c1.G,c1.B,c2.R,c2.G,c2.B))); - } - - void UpdateColorPreview(float hf, float sf, float lf, float r) - { - CurrentColorPreview1 = ColorFromHSL(hf, sf, lf); - CurrentColorPreview2 = ColorFromHSL(hf, sf, r*lf); - Game.viewport.RefreshPalette(); - } + + var colorChooser = lobby.GetWidget("COLOR_CHOOSER"); + var hueSlider = colorChooser.GetWidget("HUE_SLIDER"); + var satSlider = colorChooser.GetWidget("SAT_SLIDER"); + var lumSlider = colorChooser.GetWidget("LUM_SLIDER"); + var rangeSlider = colorChooser.GetWidget("RANGE_SLIDER"); + + hueSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + satSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + lumSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + rangeSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + + colorChooser.GetWidget("BUTTON_OK").OnMouseUp = mi => + { + colorChooser.IsVisible = () => false; + UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + UpdatePlayerColor(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + return true; + }; + } - // hk is hue in the range [0,1] instead of [0,360] - Color ColorFromHSL(float hk, float s, float l) - { - // Convert from HSL to RGB - var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s); - var p = 2 * l - q; - - float[] trgb = { hk + 1 / 3.0f, - hk, - hk - 1/3.0f }; - float[] rgb = { 0, 0, 0 }; - - for (int k = 0; k < 3; k++) - { - while (trgb[k] < 0) trgb[k] += 1.0f; - while (trgb[k] > 1) trgb[k] -= 1.0f; - } - - for (int k = 0; k < 3; k++) - { - if (trgb[k] < 1 / 6.0f) { rgb[k] = (p + ((q - p) * 6 * trgb[k])); } - else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5) { rgb[k] = q; } - else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3) { rgb[k] = (p + ((q - p) * 6 * (2.0f / 3 - trgb[k]))); } - else { rgb[k] = p; } - } - - return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255)); - } + void UpdatePlayerColor(float hf, float sf, float lf, float r) + { + var c1 = ColorFromHSL(hf, sf, lf); + var c2 = ColorFromHSL(hf, sf, r*lf); + + Game.Settings.Player.Color1 = c1; + Game.Settings.Player.Color2 = c2; + Game.Settings.Save(); + Game.IssueOrder(Order.Command("color {0},{1},{2},{3},{4},{5}".F(c1.R,c1.G,c1.B,c2.R,c2.G,c2.B))); + } + + void UpdateColorPreview(float hf, float sf, float lf, float r) + { + CurrentColorPreview1 = ColorFromHSL(hf, sf, lf); + CurrentColorPreview2 = ColorFromHSL(hf, sf, r*lf); + Game.viewport.RefreshPalette(); + } + + // hk is hue in the range [0,1] instead of [0,360] + Color ColorFromHSL(float hk, float s, float l) + { + // Convert from HSL to RGB + var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s); + var p = 2 * l - q; + + float[] trgb = { hk + 1 / 3.0f, + hk, + hk - 1/3.0f }; + float[] rgb = { 0, 0, 0 }; + + for (int k = 0; k < 3; k++) + { + while (trgb[k] < 0) trgb[k] += 1.0f; + while (trgb[k] > 1) trgb[k] -= 1.0f; + } + + for (int k = 0; k < 3; k++) + { + if (trgb[k] < 1 / 6.0f) { rgb[k] = (p + ((q - p) * 6 * trgb[k])); } + else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5) { rgb[k] = q; } + else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3) { rgb[k] = (p + ((q - p) * 6 * (2.0f / 3 - trgb[k]))); } + else { rgb[k] = p; } + } + + return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255)); + } void UpdateCurrentMap() @@ -209,23 +209,23 @@ namespace OpenRA.Widgets.Delegates MapUid = Game.LobbyInfo.GlobalSettings.Map; Map = Game.modData.AvailableMaps[MapUid]; } - - - bool hasJoined = false; - void JoinedServer() - { - if (hasJoined) - return; - hasJoined = true; - - if (Game.LocalClient.Name != Game.Settings.Player.Name) - Game.IssueOrder(Order.Command("name " + Game.Settings.Player.Name)); + + + bool hasJoined = false; + void JoinedServer() + { + if (hasJoined) + return; + hasJoined = true; + + if (Game.LocalClient.Name != Game.Settings.Player.Name) + Game.IssueOrder(Order.Command("name " + Game.Settings.Player.Name)); var c1 = Game.Settings.Player.Color1; var c2 = Game.Settings.Player.Color2; - - if (Game.LocalClient.Color1 != c1 || Game.LocalClient.Color2 != c2) - Game.IssueOrder(Order.Command("color {0},{1},{2},{3},{4},{5}".F(c1.R,c1.G,c1.B,c2.R,c2.G,c2.B))); + + if (Game.LocalClient.Color1 != c1 || Game.LocalClient.Color2 != c2) + Game.IssueOrder(Order.Command("color {0},{1},{2},{3},{4},{5}".F(c1.R,c1.G,c1.B,c2.R,c2.G,c2.B))); } void ResetConnectionState() @@ -313,24 +313,24 @@ namespace OpenRA.Widgets.Delegates name.OnLoseFocus = () => name.OnEnterKey(); var color = template.GetWidget("COLOR"); - color.OnMouseUp = mi => - { - var colorChooser = Widget.RootWidget.GetWidget("SERVER_LOBBY").GetWidget("COLOR_CHOOSER"); - var hueSlider = colorChooser.GetWidget("HUE_SLIDER"); - hueSlider.Offset = Game.LocalClient.Color1.GetHue()/360f; - - var satSlider = colorChooser.GetWidget("SAT_SLIDER"); - satSlider.Offset = Game.LocalClient.Color1.GetSaturation(); - - var lumSlider = colorChooser.GetWidget("LUM_SLIDER"); - lumSlider.Offset = Game.LocalClient.Color1.GetBrightness(); - - var rangeSlider = colorChooser.GetWidget("RANGE_SLIDER"); - rangeSlider.Offset = Game.LocalClient.Color1.GetBrightness() == 0 ? 0 : Game.LocalClient.Color2.GetBrightness()/Game.LocalClient.Color1.GetBrightness(); - - UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); - colorChooser.IsVisible = () => true; - return true; + color.OnMouseUp = mi => + { + var colorChooser = Widget.RootWidget.GetWidget("SERVER_LOBBY").GetWidget("COLOR_CHOOSER"); + var hueSlider = colorChooser.GetWidget("HUE_SLIDER"); + hueSlider.SetOffset(Game.LocalClient.Color1.GetHue()/360f); + + var satSlider = colorChooser.GetWidget("SAT_SLIDER"); + satSlider.SetOffset(Game.LocalClient.Color1.GetSaturation()); + + var lumSlider = colorChooser.GetWidget("LUM_SLIDER"); + lumSlider.SetOffset(Game.LocalClient.Color1.GetBrightness()); + + var rangeSlider = colorChooser.GetWidget("RANGE_SLIDER"); + rangeSlider.SetOffset(Game.LocalClient.Color1.GetBrightness() == 0 ? 0 : Game.LocalClient.Color2.GetBrightness()/Game.LocalClient.Color1.GetBrightness()); + + UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + colorChooser.IsVisible = () => true; + return true; }; var colorBlock = color.GetWidget("COLORBLOCK"); @@ -422,4 +422,4 @@ namespace OpenRA.Widgets.Delegates return true; } } -} \ No newline at end of file +} diff --git a/OpenRA.Game/Widgets/SliderWidget.cs b/OpenRA.Game/Widgets/SliderWidget.cs old mode 100644 new mode 100755 index 6181f311e8..3f00c59d2c --- a/OpenRA.Game/Widgets/SliderWidget.cs +++ b/OpenRA.Game/Widgets/SliderWidget.cs @@ -6,9 +6,9 @@ * as published by the Free Software Foundation. For more information, * see LICENSE. */ -#endregion - -using System; +#endregion + +using System; using System.Drawing; namespace OpenRA.Widgets @@ -17,9 +17,11 @@ namespace OpenRA.Widgets { public event Action OnChange; public Func GetOffset; - public float Offset = 0; public int Ticks = 0; public int TrackHeight = 5; + public float2 Range = new float2(0f, 1f); + + private float Offset = 0; int2 lastMouseLocation; bool isMoving = false; @@ -27,7 +29,14 @@ namespace OpenRA.Widgets public SliderWidget() : base() { - GetOffset = () => Offset; + GetOffset = () => + { + var Big = Math.Max(Range.X, Range.Y); + var Little = Math.Min(Range.X, Range.Y); + var Spread = Big - Little; + + return Spread * Offset + Little; + }; OnChange = x => Offset = x; } @@ -43,6 +52,15 @@ namespace OpenRA.Widgets isMoving = other.isMoving; } + public void SetOffset(float newOffset) + { + var Big = Math.Max(Range.X, Range.Y); + var Little = Math.Min(Range.X, Range.Y); + var Spread = Big - Little; + + Offset = (newOffset - Little) / Spread; + } + public override bool HandleInputInner(MouseInput mi) { if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) @@ -72,7 +90,7 @@ namespace OpenRA.Widgets } else if (Ticks != 0) { - var pos = GetOffset(); + var pos = Offset; // Offset slightly the direction we want to move so we don't get stuck on a tick var delta = 0.001; @@ -92,7 +110,7 @@ namespace OpenRA.Widgets var thumb = thumbRect; var center = thumb.X + thumb.Width / 2; var newOffset = OffsetBy((mi.Location.X - center) * 1f / (RenderBounds.Width - thumb.Width)); - if (newOffset != GetOffset()) + if (newOffset != Offset) { OnChange(newOffset); @@ -127,7 +145,7 @@ namespace OpenRA.Widgets float OffsetBy(float amount) { - var centerPos = GetOffset() + amount; + var centerPos = Offset + amount; if (centerPos < 0) centerPos = 0; if (centerPos > 1) centerPos = 1; return centerPos; @@ -141,7 +159,7 @@ namespace OpenRA.Widgets { var width = RenderBounds.Height; var height = RenderBounds.Height; - var origin = (int)((RenderBounds.X + width / 2) + GetOffset() * (RenderBounds.Width - width) - width / 2f); + var origin = (int)((RenderBounds.X + width / 2) + Offset * (RenderBounds.Width - width) - width / 2f); return new Rectangle(origin, RenderBounds.Y, width, height); } } @@ -169,5 +187,5 @@ namespace OpenRA.Widgets WidgetUtils.DrawPanel("dialog2", thumbRect); } } -} - +} + diff --git a/mods/cnc/chrome/gamelobby.yaml b/mods/cnc/chrome/gamelobby.yaml index 2a998414e6..397fcdfa5f 100644 --- a/mods/cnc/chrome/gamelobby.yaml +++ b/mods/cnc/chrome/gamelobby.yaml @@ -370,10 +370,12 @@ Background@SERVER_LOBBY: Slider@LUM: Id:LUM_SLIDER X:120 + Id:LUM_SLIDER Y:90 Width:260 Height:20 Ticks:5 + Range:0.2,1 Label@RANGE_LABEL: X:0 Y:120 @@ -388,6 +390,7 @@ Background@SERVER_LOBBY: Width:260 Height:20 Ticks:5 + Range:0,0.25 Background@MAP_CHOOSER: Id:MAP_CHOOSER X:(WINDOW_RIGHT - WIDTH)/2 diff --git a/mods/ra/chrome/gamelobby.yaml b/mods/ra/chrome/gamelobby.yaml index bd29783ed8..09f8d0f86d 100644 --- a/mods/ra/chrome/gamelobby.yaml +++ b/mods/ra/chrome/gamelobby.yaml @@ -371,10 +371,12 @@ Background@SERVER_LOBBY: Slider@LUM: Id:LUM_SLIDER X:120 + Id:LUM_SLIDER Y:90 Width:260 Height:20 Ticks:5 + Range:0.2,1 Label@RANGE_LABEL: X:0 Y:120 @@ -389,6 +391,7 @@ Background@SERVER_LOBBY: Width:260 Height:20 Ticks:5 + Range:0,0.25 Background@MAP_CHOOSER: Id:MAP_CHOOSER X:(WINDOW_RIGHT - WIDTH)/2