1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 08:52:55 +08:00

Fix screen dimming permanently when chat opened with no channel… (#5156)

Fix screen dimming permanently when chat opened with no channel joined

Co-authored-by: Dean Herbert <pe@ppy.sh>
This commit is contained in:
Dean Herbert 2019-07-01 19:49:36 +09:00 committed by GitHub
commit e5d3f06265
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 163 additions and 48 deletions

View File

@ -3,19 +3,23 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Online.Chat; using osu.Game.Online.Chat;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Chat; using osu.Game.Overlays.Chat;
using osu.Game.Overlays.Chat.Selection;
using osu.Game.Overlays.Chat.Tabs; using osu.Game.Overlays.Chat.Tabs;
using osu.Game.Users;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
{ {
[Description("Testing chat api and overlay")] public class TestSceneChatOverlay : ManualInputManagerTestScene
public class TestSceneChatOverlay : OsuTestScene
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
@ -28,17 +32,126 @@ namespace osu.Game.Tests.Visual.Online
typeof(TabCloseButton) typeof(TabCloseButton)
}; };
[Cached] private TestChatOverlay chatOverlay;
private readonly ChannelManager channelManager = new ChannelManager(); private ChannelManager channelManager;
[BackgroundDependencyLoader] private readonly Channel channel1 = new Channel(new User()) { Name = "test1" };
private void load() private readonly Channel channel2 = new Channel(new User()) { Name = "test2" };
[SetUp]
public void Setup()
{ {
Children = new Drawable[] Schedule(() =>
{ {
channelManager, ChannelManagerContainer container;
new ChatOverlay { State = { Value = Visibility.Visible } }
}; Child = container = new ChannelManagerContainer(new List<Channel> { channel1, channel2 })
{
RelativeSizeAxes = Axes.Both,
};
chatOverlay = container.ChatOverlay;
channelManager = container.ChannelManager;
});
}
[Test]
public void TestHideOverlay()
{
AddAssert("Chat overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
AddAssert("Selector is visible", () => chatOverlay.SelectionOverlayState == Visibility.Visible);
AddStep("Close chat overlay", () => chatOverlay.Hide());
AddAssert("Chat overlay was hidden", () => chatOverlay.State.Value == Visibility.Hidden);
AddAssert("Channel selection overlay was hidden", () => chatOverlay.SelectionOverlayState == Visibility.Hidden);
}
[Test]
public void TestSelectingChannelClosesSelector()
{
AddAssert("Selector is visible", () => chatOverlay.SelectionOverlayState == Visibility.Visible);
AddStep("Join channel 1", () => channelManager.JoinChannel(channel1));
AddStep("Switch to channel 1", () => clickDrawable(chatOverlay.TabMap[channel1]));
AddAssert("Current channel is channel 1", () => channelManager.CurrentChannel.Value == channel1);
AddAssert("Channel selector was closed", () => chatOverlay.SelectionOverlayState == Visibility.Hidden);
}
[Test]
public void TestCloseChannelWhileSelectorClosed()
{
AddStep("Join channel 1", () => channelManager.JoinChannel(channel1));
AddStep("Join channel 2", () => channelManager.JoinChannel(channel2));
AddStep("Switch to channel 2", () => clickDrawable(chatOverlay.TabMap[channel2]));
AddStep("Close channel 2", () => clickDrawable(((TestChannelTabItem)chatOverlay.TabMap[channel2]).CloseButton.Child));
AddAssert("Selector remained closed", () => chatOverlay.SelectionOverlayState == Visibility.Hidden);
AddAssert("Current channel is channel 1", () => channelManager.CurrentChannel.Value == channel1);
AddStep("Close channel 1", () => clickDrawable(((TestChannelTabItem)chatOverlay.TabMap[channel1]).CloseButton.Child));
AddAssert("Selector is visible", () => chatOverlay.SelectionOverlayState == Visibility.Visible);
}
private void clickDrawable(Drawable d)
{
InputManager.MoveMouseTo(d);
InputManager.Click(MouseButton.Left);
}
private class ChannelManagerContainer : Container
{
public TestChatOverlay ChatOverlay { get; private set; }
[Cached]
public ChannelManager ChannelManager { get; } = new ChannelManager();
private readonly List<Channel> channels;
public ChannelManagerContainer(List<Channel> channels)
{
this.channels = channels;
}
[BackgroundDependencyLoader]
private void load()
{
((BindableList<Channel>)ChannelManager.AvailableChannels).AddRange(channels);
Child = ChatOverlay = new TestChatOverlay { RelativeSizeAxes = Axes.Both, };
ChatOverlay.Show();
}
}
private class TestChatOverlay : ChatOverlay
{
public Visibility SelectionOverlayState => ChannelSelectionOverlay.State.Value;
public new ChannelSelectionOverlay ChannelSelectionOverlay => base.ChannelSelectionOverlay;
protected override ChannelTabControl CreateChannelTabControl() => new TestTabControl();
public IReadOnlyDictionary<Channel, TabItem<Channel>> TabMap => ((TestTabControl)ChannelTabControl).TabMap;
}
private class TestTabControl : ChannelTabControl
{
protected override TabItem<Channel> CreateTabItem(Channel value) => new TestChannelTabItem(value);
public new IReadOnlyDictionary<Channel, TabItem<Channel>> TabMap => base.TabMap;
}
private class TestChannelTabItem : PrivateChannelTabItem
{
public TestChannelTabItem(Channel channel)
: base(channel)
{
}
public new ClickableContainer CloseButton => base.CloseButton;
} }
} }
} }

View File

@ -32,6 +32,8 @@ namespace osu.Game.Overlays.Chat.Selection
private readonly SearchTextBox search; private readonly SearchTextBox search;
private readonly SearchContainer<ChannelSection> sectionsFlow; private readonly SearchContainer<ChannelSection> sectionsFlow;
protected override bool DimMainContent => false;
public Action<Channel> OnRequestJoin; public Action<Channel> OnRequestJoin;
public Action<Channel> OnRequestLeave; public Action<Channel> OnRequestLeave;

View File

@ -49,6 +49,8 @@ namespace osu.Game.Overlays.Chat.Tabs
// performTabSort might've made selectorTab's position wonky, fix it // performTabSort might've made selectorTab's position wonky, fix it
TabContainer.SetLayoutPosition(selectorTab, float.MaxValue); TabContainer.SetLayoutPosition(selectorTab, float.MaxValue);
((ChannelTabItem)item).OnRequestClose += tabCloseRequested;
base.AddTabItem(item, addToDropdown); base.AddTabItem(item, addToDropdown);
} }
@ -57,10 +59,10 @@ namespace osu.Game.Overlays.Chat.Tabs
switch (value.Type) switch (value.Type)
{ {
default: default:
return new ChannelTabItem(value) { OnRequestClose = tabCloseRequested }; return new ChannelTabItem(value);
case ChannelType.PM: case ChannelType.PM:
return new PrivateChannelTabItem(value) { OnRequestClose = tabCloseRequested }; return new PrivateChannelTabItem(value);
} }
} }

View File

@ -45,7 +45,9 @@ namespace osu.Game.Overlays
public const float TAB_AREA_HEIGHT = 50; public const float TAB_AREA_HEIGHT = 50;
private ChannelTabControl channelTabControl; protected ChannelTabControl ChannelTabControl;
protected virtual ChannelTabControl CreateChannelTabControl() => new ChannelTabControl();
private Container chatContainer; private Container chatContainer;
private TabsArea tabsArea; private TabsArea tabsArea;
@ -55,9 +57,10 @@ namespace osu.Game.Overlays
public Bindable<double> ChatHeight { get; set; } public Bindable<double> ChatHeight { get; set; }
private Container channelSelectionContainer; private Container channelSelectionContainer;
private ChannelSelectionOverlay channelSelectionOverlay; protected ChannelSelectionOverlay ChannelSelectionOverlay;
public override bool Contains(Vector2 screenSpacePos) => chatContainer.ReceivePositionalInputAt(screenSpacePos) || (channelSelectionOverlay.State.Value == Visibility.Visible && channelSelectionOverlay.ReceivePositionalInputAt(screenSpacePos)); public override bool Contains(Vector2 screenSpacePos) => chatContainer.ReceivePositionalInputAt(screenSpacePos)
|| (ChannelSelectionOverlay.State.Value == Visibility.Visible && ChannelSelectionOverlay.ReceivePositionalInputAt(screenSpacePos));
public ChatOverlay() public ChatOverlay()
{ {
@ -81,7 +84,7 @@ namespace osu.Game.Overlays
Masking = true, Masking = true,
Children = new[] Children = new[]
{ {
channelSelectionOverlay = new ChannelSelectionOverlay ChannelSelectionOverlay = new ChannelSelectionOverlay
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
@ -154,31 +157,25 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4.Black, Colour = Color4.Black,
}, },
channelTabControl = new ChannelTabControl ChannelTabControl = CreateChannelTabControl().With(d =>
{ {
Anchor = Anchor.BottomLeft, d.Anchor = Anchor.BottomLeft;
Origin = Anchor.BottomLeft, d.Origin = Anchor.BottomLeft;
RelativeSizeAxes = Axes.Both, d.RelativeSizeAxes = Axes.Both;
OnRequestLeave = channelManager.LeaveChannel d.OnRequestLeave = channelManager.LeaveChannel;
}, }),
} }
}, },
}, },
}, },
}; };
channelTabControl.Current.ValueChanged += current => channelManager.CurrentChannel.Value = current.NewValue; ChannelTabControl.Current.ValueChanged += current => channelManager.CurrentChannel.Value = current.NewValue;
channelTabControl.ChannelSelectorActive.ValueChanged += active => channelSelectionOverlay.State.Value = active.NewValue ? Visibility.Visible : Visibility.Hidden; ChannelTabControl.ChannelSelectorActive.ValueChanged += active => ChannelSelectionOverlay.State.Value = active.NewValue ? Visibility.Visible : Visibility.Hidden;
channelSelectionOverlay.State.ValueChanged += state => ChannelSelectionOverlay.State.ValueChanged += state =>
{ {
if (state.NewValue == Visibility.Hidden && channelManager.JoinedChannels.Count == 0) // Propagate the visibility state to ChannelSelectorActive
{ ChannelTabControl.ChannelSelectorActive.Value = state.NewValue == Visibility.Visible;
channelSelectionOverlay.Show();
Hide();
return;
}
channelTabControl.ChannelSelectorActive.Value = state.NewValue == Visibility.Visible;
if (state.NewValue == Visibility.Visible) if (state.NewValue == Visibility.Visible)
{ {
@ -190,8 +187,8 @@ namespace osu.Game.Overlays
textbox.HoldFocus = true; textbox.HoldFocus = true;
}; };
channelSelectionOverlay.OnRequestJoin = channel => channelManager.JoinChannel(channel); ChannelSelectionOverlay.OnRequestJoin = channel => channelManager.JoinChannel(channel);
channelSelectionOverlay.OnRequestLeave = channelManager.LeaveChannel; ChannelSelectionOverlay.OnRequestLeave = channelManager.LeaveChannel;
ChatHeight = config.GetBindable<double>(OsuSetting.ChatDisplayHeight); ChatHeight = config.GetBindable<double>(OsuSetting.ChatDisplayHeight);
ChatHeight.ValueChanged += height => ChatHeight.ValueChanged += height =>
@ -217,11 +214,11 @@ namespace osu.Game.Overlays
channelManager.JoinedChannels.ItemsAdded += onChannelAddedToJoinedChannels; channelManager.JoinedChannels.ItemsAdded += onChannelAddedToJoinedChannels;
channelManager.JoinedChannels.ItemsRemoved += onChannelRemovedFromJoinedChannels; channelManager.JoinedChannels.ItemsRemoved += onChannelRemovedFromJoinedChannels;
foreach (Channel channel in channelManager.JoinedChannels) foreach (Channel channel in channelManager.JoinedChannels)
channelTabControl.AddChannel(channel); ChannelTabControl.AddChannel(channel);
channelManager.AvailableChannels.ItemsAdded += availableChannelsChanged; channelManager.AvailableChannels.ItemsAdded += availableChannelsChanged;
channelManager.AvailableChannels.ItemsRemoved += availableChannelsChanged; channelManager.AvailableChannels.ItemsRemoved += availableChannelsChanged;
channelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels); ChannelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels);
currentChannel = channelManager.CurrentChannel.GetBoundCopy(); currentChannel = channelManager.CurrentChannel.GetBoundCopy();
currentChannel.BindValueChanged(currentChannelChanged, true); currentChannel.BindValueChanged(currentChannelChanged, true);
@ -236,7 +233,7 @@ namespace osu.Game.Overlays
{ {
textbox.Current.Disabled = true; textbox.Current.Disabled = true;
currentChannelContainer.Clear(false); currentChannelContainer.Clear(false);
channelSelectionOverlay.Show(); ChannelSelectionOverlay.Show();
return; return;
} }
@ -245,8 +242,8 @@ namespace osu.Game.Overlays
textbox.Current.Disabled = e.NewValue.ReadOnly; textbox.Current.Disabled = e.NewValue.ReadOnly;
if (channelTabControl.Current.Value != e.NewValue) if (ChannelTabControl.Current.Value != e.NewValue)
Scheduler.Add(() => channelTabControl.Current.Value = e.NewValue); Scheduler.Add(() => ChannelTabControl.Current.Value = e.NewValue);
var loaded = loadedChannels.Find(d => d.Channel == e.NewValue); var loaded = loadedChannels.Find(d => d.Channel == e.NewValue);
@ -294,7 +291,7 @@ namespace osu.Game.Overlays
double targetChatHeight = startDragChatHeight - (e.MousePosition.Y - e.MouseDownPosition.Y) / Parent.DrawSize.Y; double targetChatHeight = startDragChatHeight - (e.MousePosition.Y - e.MouseDownPosition.Y) / Parent.DrawSize.Y;
// If the channel selection screen is shown, mind its minimum height // If the channel selection screen is shown, mind its minimum height
if (channelSelectionOverlay.State.Value == Visibility.Visible && targetChatHeight > 1f - channel_selection_min_height) if (ChannelSelectionOverlay.State.Value == Visibility.Visible && targetChatHeight > 1f - channel_selection_min_height)
targetChatHeight = 1f - channel_selection_min_height; targetChatHeight = 1f - channel_selection_min_height;
ChatHeight.Value = targetChatHeight; ChatHeight.Value = targetChatHeight;
@ -311,9 +308,9 @@ namespace osu.Game.Overlays
private void selectTab(int index) private void selectTab(int index)
{ {
var channel = channelTabControl.Items.Skip(index).FirstOrDefault(); var channel = ChannelTabControl.Items.Skip(index).FirstOrDefault();
if (channel != null && !(channel is ChannelSelectorTabItem.ChannelSelectorTabChannel)) if (channel != null && !(channel is ChannelSelectorTabItem.ChannelSelectorTabChannel))
channelTabControl.Current.Value = channel; ChannelTabControl.Current.Value = channel;
} }
protected override bool OnKeyDown(KeyDownEvent e) protected override bool OnKeyDown(KeyDownEvent e)
@ -358,6 +355,7 @@ namespace osu.Game.Overlays
this.FadeIn(transition_length, Easing.OutQuint); this.FadeIn(transition_length, Easing.OutQuint);
textbox.HoldFocus = true; textbox.HoldFocus = true;
base.PopIn(); base.PopIn();
} }
@ -366,7 +364,7 @@ namespace osu.Game.Overlays
this.MoveToY(Height, transition_length, Easing.InSine); this.MoveToY(Height, transition_length, Easing.InSine);
this.FadeOut(transition_length, Easing.InSine); this.FadeOut(transition_length, Easing.InSine);
channelSelectionOverlay.Hide(); ChannelSelectionOverlay.Hide();
textbox.HoldFocus = false; textbox.HoldFocus = false;
base.PopOut(); base.PopOut();
@ -375,20 +373,20 @@ namespace osu.Game.Overlays
private void onChannelAddedToJoinedChannels(IEnumerable<Channel> channels) private void onChannelAddedToJoinedChannels(IEnumerable<Channel> channels)
{ {
foreach (Channel channel in channels) foreach (Channel channel in channels)
channelTabControl.AddChannel(channel); ChannelTabControl.AddChannel(channel);
} }
private void onChannelRemovedFromJoinedChannels(IEnumerable<Channel> channels) private void onChannelRemovedFromJoinedChannels(IEnumerable<Channel> channels)
{ {
foreach (Channel channel in channels) foreach (Channel channel in channels)
{ {
channelTabControl.RemoveChannel(channel); ChannelTabControl.RemoveChannel(channel);
loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel)); loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel));
} }
} }
private void availableChannelsChanged(IEnumerable<Channel> channels) private void availableChannelsChanged(IEnumerable<Channel> channels)
=> channelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels); => ChannelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels);
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {