From fa5c8d083ed2ed2204583d37e8778144358738b5 Mon Sep 17 00:00:00 2001 From: Pavlos Touboulidis Date: Fri, 25 Apr 2014 17:34:00 +0300 Subject: [PATCH 1/7] Fix chat line expiration The chat display overlay would remove one chat line every X ticks. It will now keep track of the time each chat line has to be removed and act accordingly. For example, if 3 chat lines are added with 1 second difference from each other, they will be removed one after the other, with the same 1 second difference. --- OpenRA.Game/Widgets/ChatDisplayWidget.cs | 28 +++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/OpenRA.Game/Widgets/ChatDisplayWidget.cs b/OpenRA.Game/Widgets/ChatDisplayWidget.cs index ea0ecda348..d7e5e964bf 100644 --- a/OpenRA.Game/Widgets/ChatDisplayWidget.cs +++ b/OpenRA.Game/Widgets/ChatDisplayWidget.cs @@ -22,7 +22,7 @@ namespace OpenRA.Widgets public string Notification = ""; const int logLength = 9; - int ticksUntilRemove = 0; + uint totalTicks; internal List recentLines = new List(); @@ -69,8 +69,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, totalTicks + (uint)RemoveTime, c)); if (Notification != null) Sound.Play(Notification); @@ -92,20 +91,29 @@ namespace OpenRA.Widgets public override void Tick() { + totalTicks++; + 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 && totalTicks >= 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 uint Expiration; + + public ChatLine(string owner, string text, uint expiration, Color color) + { + this.Owner = owner; + this.Text = text; + this.Expiration = expiration; + this.Color = color; + } } } \ No newline at end of file From 4f12882706a51c860041226c7f0ca59d70b0a816 Mon Sep 17 00:00:00 2001 From: Pavlos Touboulidis Date: Fri, 25 Apr 2014 17:40:00 +0300 Subject: [PATCH 2/7] Minor clean up --- OpenRA.Game/Widgets/ChatDisplayWidget.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/OpenRA.Game/Widgets/ChatDisplayWidget.cs b/OpenRA.Game/Widgets/ChatDisplayWidget.cs index d7e5e964bf..8c8e22eba8 100644 --- a/OpenRA.Game/Widgets/ChatDisplayWidget.cs +++ b/OpenRA.Game/Widgets/ChatDisplayWidget.cs @@ -23,8 +23,7 @@ namespace OpenRA.Widgets const int logLength = 9; uint totalTicks; - - internal List recentLines = new List(); + List recentLines = new List(); public override Rectangle EventBounds { get { return Rectangle.Empty; } } @@ -84,11 +83,6 @@ namespace OpenRA.Widgets recentLines.RemoveAt(0); } - public void ClearChat() - { - recentLines = new List(); - } - public override void Tick() { totalTicks++; From ef066560ad289c921794e01d14298e0f936f5d47 Mon Sep 17 00:00:00 2001 From: Pavlos Touboulidis Date: Fri, 25 Apr 2014 18:11:44 +0300 Subject: [PATCH 3/7] Fix text-wrapping special case If a line of text contained a whole word that was longer than the allotted space, it would fail to wrap that line completely, even if it was possible to wrap at other locations. Fixing this uncovered a second issue, where it would drop the last line if the input had more than one lines and one of the first ones was wider than the specified width. --- OpenRA.Game/Exts.cs | 2 +- OpenRA.Game/Widgets/WidgetUtils.cs | 46 +++++++++++------------------- 2 files changed, 17 insertions(+), 31 deletions(-) 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/WidgetUtils.cs b/OpenRA.Game/Widgets/WidgetUtils.cs index 6465b4f3ea..7ab7270407 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 (int i=0; i width) { - if (-1 == (spaceIndex = line.LastIndexOf(' ', start))) + int 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; } From e5e97c9a11fb7bac0eea70c9ec5a77cf11df7844 Mon Sep 17 00:00:00 2001 From: Pavlos Touboulidis Date: Fri, 25 Apr 2014 18:17:29 +0300 Subject: [PATCH 4/7] Fix issue #5149: Make chat window not autoscroll It will autoscroll unless the chat window is open and the scroll position is not at the bottom. --- OpenRA.Game/Widgets/ChatDisplayWidget.cs | 2 +- OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/Widgets/ChatDisplayWidget.cs b/OpenRA.Game/Widgets/ChatDisplayWidget.cs index 8c8e22eba8..affee3f5ad 100644 --- a/OpenRA.Game/Widgets/ChatDisplayWidget.cs +++ b/OpenRA.Game/Widgets/ChatDisplayWidget.cs @@ -91,7 +91,7 @@ namespace OpenRA.Widgets return; // This takes advantage of the fact that recentLines is ordered by expiration, from sooner to later - while (recentLines.Count > 0 && totalTicks >= recentLines [0].Expiration) + while (recentLines.Count > 0 && totalTicks >= recentLines[0].Expiration) recentLines.RemoveAt(0); } } 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); } } From ddabe080cd07ad08d36473fb67875dc5eecdc065 Mon Sep 17 00:00:00 2001 From: Pavlos Touboulidis Date: Sat, 26 Apr 2014 03:18:12 +0300 Subject: [PATCH 5/7] Style fixes --- OpenRA.Game/Widgets/ChatDisplayWidget.cs | 8 ++++---- OpenRA.Game/Widgets/WidgetUtils.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenRA.Game/Widgets/ChatDisplayWidget.cs b/OpenRA.Game/Widgets/ChatDisplayWidget.cs index affee3f5ad..e7bd0ee837 100644 --- a/OpenRA.Game/Widgets/ChatDisplayWidget.cs +++ b/OpenRA.Game/Widgets/ChatDisplayWidget.cs @@ -104,10 +104,10 @@ namespace OpenRA.Widgets public ChatLine(string owner, string text, uint expiration, Color color) { - this.Owner = owner; - this.Text = text; - this.Expiration = expiration; - this.Color = color; + Owner = owner; + Text = text; + Expiration = expiration; + Color = color; } } } \ No newline at end of file diff --git a/OpenRA.Game/Widgets/WidgetUtils.cs b/OpenRA.Game/Widgets/WidgetUtils.cs index 7ab7270407..573a824d80 100644 --- a/OpenRA.Game/Widgets/WidgetUtils.cs +++ b/OpenRA.Game/Widgets/WidgetUtils.cs @@ -172,7 +172,7 @@ namespace OpenRA.Widgets { var lines = text.Split('\n').ToList(); - for (int i=0; i width) { - int spaceIndex = line.LastIndexOf(' ', start); + var spaceIndex = line.LastIndexOf(' ', start); if (spaceIndex == -1) break; bestSpaceIndex = spaceIndex; From c099e6d09bb7253c790fa94c0b6e5897954bc180 Mon Sep 17 00:00:00 2001 From: Pavlos Touboulidis Date: Sat, 26 Apr 2014 03:18:46 +0300 Subject: [PATCH 6/7] Fix overlay chat lines expiration It wasn't working right when the widget was hidden because it wasn't receiving any Ticks. Instead of counting, we're now using Game.LocalTick as the tick source. --- OpenRA.Game/Widgets/ChatDisplayWidget.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/OpenRA.Game/Widgets/ChatDisplayWidget.cs b/OpenRA.Game/Widgets/ChatDisplayWidget.cs index e7bd0ee837..33f5892f56 100644 --- a/OpenRA.Game/Widgets/ChatDisplayWidget.cs +++ b/OpenRA.Game/Widgets/ChatDisplayWidget.cs @@ -22,7 +22,6 @@ namespace OpenRA.Widgets public string Notification = ""; const int logLength = 9; - uint totalTicks; List recentLines = new List(); public override Rectangle EventBounds { get { return Rectangle.Empty; } } @@ -68,7 +67,7 @@ namespace OpenRA.Widgets public void AddLine(Color c, string from, string text) { - recentLines.Add(new ChatLine(from, text, totalTicks + (uint)RemoveTime, c)); + recentLines.Add(new ChatLine(from, text, Game.LocalTick + RemoveTime, c)); if (Notification != null) Sound.Play(Notification); @@ -85,13 +84,11 @@ namespace OpenRA.Widgets public override void Tick() { - totalTicks++; - if (RemoveTime == 0) return; // This takes advantage of the fact that recentLines is ordered by expiration, from sooner to later - while (recentLines.Count > 0 && totalTicks >= recentLines[0].Expiration) + while (recentLines.Count > 0 && Game.LocalTick >= recentLines[0].Expiration) recentLines.RemoveAt(0); } } @@ -100,9 +97,9 @@ namespace OpenRA.Widgets { public readonly Color Color; public readonly string Owner, Text; - public readonly uint Expiration; + public readonly int Expiration; - public ChatLine(string owner, string text, uint expiration, Color color) + public ChatLine(string owner, string text, int expiration, Color color) { Owner = owner; Text = text; From af48626020bf0bc87c8a8ff9b56950e6e1a8c847 Mon Sep 17 00:00:00 2001 From: Pavlos Touboulidis Date: Sat, 26 Apr 2014 17:21:42 +0300 Subject: [PATCH 7/7] Fix scroll offsets This is not a full fix, it merely restores the functionality already present. The ScrollPanelWidget does not work right if Align is set to Bottom but ScrollToBottom() isn't called after adding items and there's not enough content to scroll. --- OpenRA.Game/Widgets/ScrollPanelWidget.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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)