diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs index 4fe0cb685e..efa4cd41b3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs @@ -8,7 +8,7 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Overlays.Chat; +using osu.Game.Graphics.UserInterface; using osuTK.Input; namespace osu.Game.Tests.Visual.Online @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneChatManipulation : OsuManualInputManagerTestScene { - private ChatTextBox box; + private HistoryTextBox box; private OsuSpriteText text; [SetUp] @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual.Online { Children = new Drawable[] { - box = new ChatTextBox + box = new HistoryTextBox(5) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -56,6 +56,75 @@ namespace osu.Game.Tests.Visual.Online }); } + [Test] + public void TestEmptyHistory() + { + const string temp = "Temp message"; + AddStep("Set text", () => box.Text = temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is the same", () => box.Text == temp); + + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddAssert("Text is the same", () => box.Text == temp); + } + + [Test] + public void TestPartialHistory() + { + addMessages(2); + + const string temp = "Temp message"; + AddStep("Set text", () => box.Text = temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is the same", () => box.Text == temp); + + AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 2); + AddAssert("Same as 1st message", () => box.Text == "Message 1"); + + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddAssert("Text is the same", () => box.Text == "Message 1"); + + AddRepeatStep("Move down", () => InputManager.Key(Key.Down), 2); + AddAssert("Same as temp message", () => box.Text == temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is the same", () => box.Text == temp); + } + + [Test] + public void TestFullHistory() + { + addMessages(5); + AddAssert("History saved as <1-5>", () => + Enumerable.Range(1, 5).Select(number => $"Message {number}").SequenceEqual(box.MessageHistory)); + + const string temp = "Temp message"; + AddStep("Set text", () => box.Text = temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is the same", () => box.Text == temp); + + addMessages(2); + AddAssert("Overwrote history to <3-7>", () => + Enumerable.Range(3, 5).Select(number => $"Message {number}").SequenceEqual(box.MessageHistory)); + + AddStep("Set text", () => box.Text = temp); + + AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 5); + AddAssert("Same as 3rd message", () => box.Text == "Message 3"); + + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddAssert("Text is the same", () => box.Text == "Message 3"); + + AddRepeatStep("Move down", () => InputManager.Key(Key.Down), 4); + AddAssert("Same as previous message", () => box.Text == "Message 7"); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Same as temp message", () => box.Text == temp); + } + [Test] public void TestStayOnLastIndex() { diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 96c0734d63..c91e5dcb41 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using osu.Framework.Input.Events; using osuTK.Input; @@ -9,50 +10,71 @@ namespace osu.Game.Graphics.UserInterface { public class HistoryTextBox : FocusedTextBox { - private readonly List messageHistory = new List(); + private readonly int historyLimit; + + private readonly List messageHistory; public IReadOnlyList MessageHistory => messageHistory; - private int historyIndex; + private int startIndex; private string originalMessage = string.Empty; + private int nullIndex => -1; + private int historyIndex = -1; + private int endIndex => (messageHistory.Count + startIndex - 1) % Math.Max(1, messageHistory.Count); - public HistoryTextBox() + public HistoryTextBox(int historyLimit = 100) { + this.historyLimit = historyLimit; + messageHistory = new List(historyLimit); + Current.ValueChanged += text => { if (string.IsNullOrEmpty(text.NewValue)) - historyIndex = messageHistory.Count; + historyIndex = nullIndex; }; } + public string GetOldMessage(int index) + { + if (index < 0 || index >= messageHistory.Count) + throw new ArgumentOutOfRangeException(); + + return messageHistory[(startIndex + index) % messageHistory.Count]; + } + protected override bool OnKeyDown(KeyDownEvent e) { switch (e.Key) { case Key.Up: - if (historyIndex == messageHistory.Count) + if (historyIndex == nullIndex) + { + historyIndex = endIndex; originalMessage = Text; + } - if (historyIndex == 0) + if (historyIndex == startIndex) return true; - Text = messageHistory[--historyIndex]; + historyIndex = (historyLimit + historyIndex - 1) % historyLimit; + Text = messageHistory[historyIndex]; return true; case Key.Down: - if (historyIndex == messageHistory.Count) + if (historyIndex == nullIndex) return true; - if (historyIndex == messageHistory.Count - 1) + if (historyIndex == endIndex) { - historyIndex = messageHistory.Count; + historyIndex = nullIndex; Text = originalMessage; return true; } - Text = messageHistory[++historyIndex]; + historyIndex = (historyIndex + 1) % historyLimit; + Text = messageHistory[historyIndex]; return true; } @@ -63,9 +85,18 @@ namespace osu.Game.Graphics.UserInterface protected override void Commit() { if (!string.IsNullOrEmpty(Text)) - messageHistory.Add(Text); + { + if (messageHistory.Count == historyLimit) + { + messageHistory[startIndex++] = Text; + } + else + { + messageHistory.Add(Text); + } + } - historyIndex = messageHistory.Count; + historyIndex = nullIndex; base.Commit(); }