diff --git a/OpenRA.Game/Exts.cs b/OpenRA.Game/Exts.cs index 8ee1b34341..41d98389b0 100755 --- a/OpenRA.Game/Exts.cs +++ b/OpenRA.Game/Exts.cs @@ -149,7 +149,7 @@ namespace OpenRA public static string JoinWith(this IEnumerable ts, string j) { - return string.Join(j, ts.Select(t => t.ToString()).ToArray()); + return string.Join(j, ts); } public static IEnumerable Append(this IEnumerable ts, params T[] moreTs) diff --git a/OpenRA.Game/Widgets/ChatDisplayWidget.cs b/OpenRA.Game/Widgets/ChatDisplayWidget.cs index ea0ecda348..33f5892f56 100644 --- a/OpenRA.Game/Widgets/ChatDisplayWidget.cs +++ b/OpenRA.Game/Widgets/ChatDisplayWidget.cs @@ -22,9 +22,7 @@ namespace OpenRA.Widgets public string Notification = ""; const int logLength = 9; - int ticksUntilRemove = 0; - - internal List recentLines = new List(); + List recentLines = new List(); public override Rectangle EventBounds { get { return Rectangle.Empty; } } @@ -69,8 +67,7 @@ namespace OpenRA.Widgets public void AddLine(Color c, string from, string text) { - recentLines.Add(new ChatLine { Color = c, Owner = from, Text = text }); - ticksUntilRemove = RemoveTime; + recentLines.Add(new ChatLine(from, text, Game.LocalTick + RemoveTime, c)); if (Notification != null) Sound.Play(Notification); @@ -85,27 +82,29 @@ namespace OpenRA.Widgets recentLines.RemoveAt(0); } - public void ClearChat() - { - recentLines = new List(); - } - public override void Tick() { if (RemoveTime == 0) return; - if (--ticksUntilRemove > 0) - return; - - ticksUntilRemove = RemoveTime; - RemoveLine(); + // This takes advantage of the fact that recentLines is ordered by expiration, from sooner to later + while (recentLines.Count > 0 && Game.LocalTick >= recentLines[0].Expiration) + recentLines.RemoveAt(0); } } class ChatLine { - public Color Color = Color.White; - public string Owner, Text; + public readonly Color Color; + public readonly string Owner, Text; + public readonly int Expiration; + + public ChatLine(string owner, string text, int expiration, Color color) + { + Owner = owner; + Text = text; + Expiration = expiration; + Color = color; + } } } \ No newline at end of file diff --git a/OpenRA.Game/Widgets/ScrollPanelWidget.cs b/OpenRA.Game/Widgets/ScrollPanelWidget.cs index b5c8be5fa2..e0e04bac3f 100644 --- a/OpenRA.Game/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Game/Widgets/ScrollPanelWidget.cs @@ -151,7 +151,7 @@ namespace OpenRA.Widgets public bool ScrolledToBottom { - get { return ListOffset == Math.Min(0, Bounds.Height - ContentHeight); } + get { return ListOffset == Math.Min(0, Bounds.Height - ContentHeight) || ContentHeight <= Bounds.Height; } } public void ScrollToItem(string itemKey) diff --git a/OpenRA.Game/Widgets/WidgetUtils.cs b/OpenRA.Game/Widgets/WidgetUtils.cs index 6465b4f3ea..573a824d80 100644 --- a/OpenRA.Game/Widgets/WidgetUtils.cs +++ b/OpenRA.Game/Widgets/WidgetUtils.cs @@ -170,52 +170,38 @@ namespace OpenRA.Widgets var textSize = font.Measure(text); if (textSize.X > width) { - var lines = text.Split('\n'); - var newLines = new List(); - var i = 0; - var line = lines[i++]; + var lines = text.Split('\n').ToList(); - for(;;) + for (var i=0; i width) { - if (-1 == (spaceIndex = line.LastIndexOf(' ', start))) + var spaceIndex = line.LastIndexOf(' ', start); + if (spaceIndex == -1) break; + bestSpaceIndex = spaceIndex; + start = spaceIndex - 1; m = font.Measure(line.Substring(0, spaceIndex)); } - if (spaceIndex != -1) + if (bestSpaceIndex != -1) { - newLines.RemoveAt(newLines.Count - 1); - newLines.Add(line.Substring(0, spaceIndex)); - line = line.Substring(spaceIndex + 1); + lines[i] = line.Substring(0, bestSpaceIndex); + lines.Insert(i + 1, line.Substring(bestSpaceIndex + 1)); } - else if (i < lines.Length - 1) - { - line = lines[i++]; - continue; - } - else - break; } - return newLines.JoinWith("\n"); + + return string.Join("\n", lines); } return text; } diff --git a/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs index 3a0d3c541f..54734050bc 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs @@ -146,8 +146,11 @@ namespace OpenRA.Mods.RA.Widgets.Logic template.Bounds.Height += dh; } + bool scrolledToBottom = chatScrollPanel.ScrolledToBottom; chatScrollPanel.AddChild(template); - chatScrollPanel.ScrollToBottom(); + if (scrolledToBottom) + chatScrollPanel.ScrollToBottom(); + Sound.PlayNotification(null, "Sounds", "ChatLine", null); } }