From 5a953f38119cdca4a3a6a214110b2d2f934ab013 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 10 Dec 2021 19:14:33 +0900 Subject: [PATCH 01/15] Fix autopilot not working as expected on touch devices Closes https://github.com/ppy/osu/issues/12731. I haven't tested this, but quite confident it should work. Will test later today unless someone else beats me. --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 7314021a14..f5fc3de381 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.ComponentModel; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Framework.Input.StateChanges.Events; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu @@ -39,6 +40,17 @@ namespace osu.Game.Rulesets.Osu return base.Handle(e); } + protected override bool HandleMouseTouchStateChange(TouchStateChangeEvent e) + { + if (!AllowUserCursorMovement) + { + // Still allow for forwarding of the "touch" part, but block the positional data. + e = new TouchStateChangeEvent(e.State, e.Input, e.Touch, false, null); + } + + return base.HandleMouseTouchStateChange(e); + } + private class OsuKeyBindingContainer : RulesetKeyBindingContainer { public bool AllowUserPresses = true; From bc1f1f35b5a73dde39bfaab211300df330f5f7f3 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 10 Dec 2021 16:40:51 +0300 Subject: [PATCH 02/15] Remove now redundant inclusion of `TouchMoveEvent` in `OsuInputManager.Handle` Now it's handled separately via the `HandleMouseTouchStateChange` override. --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index f5fc3de381..57704b3bd8 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu protected override bool Handle(UIEvent e) { - if ((e is MouseMoveEvent || e is TouchMoveEvent) && !AllowUserCursorMovement) return false; + if (e is MouseMoveEvent && !AllowUserCursorMovement) return false; return base.Handle(e); } From cf3041128888b4be5993728e8604c90df1cdd49b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 10 Dec 2021 17:13:13 +0300 Subject: [PATCH 03/15] Revert "Remove now redundant inclusion of `TouchMoveEvent` in `OsuInputManager.Handle`" This reverts commit bc1f1f35b5a73dde39bfaab211300df330f5f7f3. --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 57704b3bd8..f5fc3de381 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu protected override bool Handle(UIEvent e) { - if (e is MouseMoveEvent && !AllowUserCursorMovement) return false; + if ((e is MouseMoveEvent || e is TouchMoveEvent) && !AllowUserCursorMovement) return false; return base.Handle(e); } From 0c11fe741309f8b990f4d85b69080dd9beb53f55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Dec 2021 12:45:09 +0900 Subject: [PATCH 04/15] Fix toast popups spamming samples when adjusting osu!mania scroll speed during gameplay Not the most robust of fixes, but as per the reasoning described in the issue thread, a proper fix will take considerably more effort. This intends to fix the issue first and foremost, as it sounds so bad I'd want to mute my sound before adjusting currently. Closes #15718. --- osu.Game/Overlays/OSD/TrackedSettingToast.cs | 24 ++++++++++++++++++++ osu.Game/Overlays/OnScreenDisplay.cs | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OSD/TrackedSettingToast.cs b/osu.Game/Overlays/OSD/TrackedSettingToast.cs index 51214fe460..9939ba024e 100644 --- a/osu.Game/Overlays/OSD/TrackedSettingToast.cs +++ b/osu.Game/Overlays/OSD/TrackedSettingToast.cs @@ -5,12 +5,14 @@ using System; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; +using osu.Game.Configuration; using osu.Game.Graphics; using osuTK; using osuTK.Graphics; @@ -28,6 +30,8 @@ namespace osu.Game.Overlays.OSD private Sample sampleOff; private Sample sampleChange; + private Bindable lastPlaybackTime; + public TrackedSettingToast(SettingDescription description) : base(description.Name, description.Value, description.Shortcut) { @@ -75,10 +79,28 @@ namespace osu.Game.Overlays.OSD optionLights.Add(new OptionLight { Glowing = i == selectedOption }); } + [Resolved] + private SessionStatics statics { get; set; } + protected override void LoadComplete() { base.LoadComplete(); + playSound(); + } + + private void playSound() + { + // This debounce code roughly follows what we're using in HoverSampleDebounceComponent. + // We're sharing the existing static for hover sounds because it doesn't really matter if they block each other. + // This is a simple solution, but if this ever becomes a problem (or other performance issues arise), + // the whole toast system should be rewritten to avoid recreating this drawable each time a value changes. + lastPlaybackTime = statics.GetBindable(Static.LastHoverSoundPlaybackTime); + + bool enoughTimePassedSinceLastPlayback = !lastPlaybackTime.Value.HasValue || Time.Current - lastPlaybackTime.Value >= OsuGameBase.SAMPLE_DEBOUNCE_TIME; + + if (!enoughTimePassedSinceLastPlayback) return; + if (optionCount == 1) { if (selectedOption == 0) @@ -93,6 +115,8 @@ namespace osu.Game.Overlays.OSD sampleChange.Frequency.Value = 1 + (double)selectedOption / (optionCount - 1) * 0.25f; sampleChange.Play(); } + + lastPlaybackTime.Value = Time.Current; } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index be9d3cd794..6b3696ced9 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -101,7 +101,7 @@ namespace osu.Game.Overlays DisplayTemporarily(box); }); - private void displayTrackedSettingChange(SettingDescription description) => Display(new TrackedSettingToast(description)); + private void displayTrackedSettingChange(SettingDescription description) => Scheduler.AddOnce(Display, new TrackedSettingToast(description)); private TransformSequence fadeIn; private ScheduledDelegate fadeOut; From e9187cc3cf3192b3559b23b7c4cf5a60d4b1832a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Dec 2021 16:13:12 +0900 Subject: [PATCH 05/15] Add failing test showing expanded state being unexpectedly lost --- .../Visual/Beatmaps/TestSceneBeatmapCard.cs | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs index f835d21603..0b9857486a 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs @@ -6,12 +6,12 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; using osu.Game.Beatmaps.Drawables.Cards; using osu.Game.Graphics.Containers; using osu.Game.Online.API; @@ -19,11 +19,10 @@ using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osuTK; -using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.Beatmaps { - public class TestSceneBeatmapCard : OsuTestScene + public class TestSceneBeatmapCard : OsuManualInputManagerTestScene { /// /// All cards on this scene use a common online ID to ensure that map download, preview tracks, etc. can be tested manually with online sources. @@ -253,14 +252,32 @@ namespace osu.Game.Tests.Visual.Beatmaps public void TestNormal() { createTestCase(beatmapSetInfo => new BeatmapCard(beatmapSetInfo)); + } - AddToggleStep("toggle expanded state", expanded => - { - var card = this.ChildrenOfType().Last(); - if (!card.Expanded.Disabled) - card.Expanded.Value = expanded; - }); - AddToggleStep("disable/enable expansion", disabled => this.ChildrenOfType().ForEach(card => card.Expanded.Disabled = disabled)); + [Test] + public void TestHoverState() + { + AddStep("create cards", () => Child = createContent(OverlayColourScheme.Blue, s => new BeatmapCard(s))); + + AddStep("Hover card", () => InputManager.MoveMouseTo(firstCard())); + AddWaitStep("wait for potential state change", 5); + AddAssert("card is not expanded", () => !firstCard().Expanded.Value); + + AddStep("Hover spectrum display", () => InputManager.MoveMouseTo(firstCard().ChildrenOfType().Single())); + AddUntilStep("card is expanded", () => firstCard().Expanded.Value); + + AddStep("Hover difficulty content", () => InputManager.MoveMouseTo(firstCard().ChildrenOfType().Single())); + AddWaitStep("wait for potential state change", 5); + AddAssert("card is still expanded", () => firstCard().Expanded.Value); + + AddStep("Hover main content again", () => InputManager.MoveMouseTo(firstCard())); + AddWaitStep("wait for potential state change", 5); + AddAssert("card is still expanded", () => firstCard().Expanded.Value); + + AddStep("Hover away", () => InputManager.MoveMouseTo(this.ChildrenOfType().Last())); + AddUntilStep("card is not expanded", () => !firstCard().Expanded.Value); + + BeatmapCard firstCard() => this.ChildrenOfType().First(); } } } From 41e6c24dad8750edd2115c12ecd6857252036b46 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Dec 2021 15:51:47 +0900 Subject: [PATCH 06/15] Expose `Expanded` state of `BeatmapCardContent` as read-only bindable This is just to reduce complexity of these interactions by ensuring that the expanded state can only be changed by the class itself. --- .../Beatmaps/Drawables/Cards/BeatmapCardContent.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs index 681f09c658..e353e61b71 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs @@ -31,7 +31,9 @@ namespace osu.Game.Beatmaps.Drawables.Cards set => dropdownScroll.Child = value; } - public Bindable Expanded { get; } = new BindableBool(); + public IBindable Expanded => expanded; + + private readonly BindableBool expanded = new BindableBool(); private readonly Box background; private readonly Container content; @@ -128,7 +130,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards scheduledExpandedChange = Scheduler.AddDelayed(() => { if (!Expanded.Disabled) - Expanded.Value = true; + expanded.Value = true; }, 100); } @@ -141,7 +143,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards scheduledExpandedChange = Scheduler.AddDelayed(() => { if (!Expanded.Disabled) - Expanded.Value = false; + expanded.Value = false; }, 500); } @@ -154,7 +156,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards return; scheduledExpandedChange?.Cancel(); - Expanded.Value = false; + expanded.Value = false; } private void keep() @@ -163,7 +165,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards return; scheduledExpandedChange?.Cancel(); - Expanded.Value = true; + expanded.Value = true; } private void updateState() From ef4ab74565a843d23da2e05bc01a7ace7478a353 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Dec 2021 16:19:47 +0900 Subject: [PATCH 07/15] Also only expose `Expanded` state of `BeatmapCard` as read-only --- osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs | 6 ++++-- osu.Game/Screens/Play/SoloSpectator.cs | 5 +---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index d93ac841ab..435a8227bd 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -33,7 +33,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards public const float TRANSITION_DURATION = 400; public const float CORNER_RADIUS = 10; - public Bindable Expanded { get; } = new BindableBool(); + public IBindable Expanded { get; } private const float width = 408; private const float height = 100; @@ -64,9 +64,11 @@ namespace osu.Game.Beatmaps.Drawables.Cards [Resolved] private OverlayColourProvider colourProvider { get; set; } = null!; - public BeatmapCard(APIBeatmapSet beatmapSet) + public BeatmapCard(APIBeatmapSet beatmapSet, bool allowExpansion = true) : base(HoverSampleSet.Submit) { + Expanded = new BindableBool { Disabled = !allowExpansion }; + this.beatmapSet = beatmapSet; favouriteState = new Bindable(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount)); downloadTracker = new BeatmapDownloadTracker(beatmapSet); diff --git a/osu.Game/Screens/Play/SoloSpectator.cs b/osu.Game/Screens/Play/SoloSpectator.cs index 3918dbe8fc..ba5663bfa3 100644 --- a/osu.Game/Screens/Play/SoloSpectator.cs +++ b/osu.Game/Screens/Play/SoloSpectator.cs @@ -228,10 +228,7 @@ namespace osu.Game.Screens.Play onlineBeatmapRequest.Success += beatmapSet => Schedule(() => { this.beatmapSet = beatmapSet; - beatmapPanelContainer.Child = new BeatmapCard(this.beatmapSet) - { - Expanded = { Disabled = true } - }; + beatmapPanelContainer.Child = new BeatmapCard(this.beatmapSet, allowExpansion: false); checkForAutomaticDownload(); }); From 7a9db22c5240a600b87a40b74cc6416cc0d9122f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Dec 2021 16:02:43 +0900 Subject: [PATCH 08/15] Tidy up method naming and structure for expanded state changes --- .../Beatmaps/Drawables/Cards/BeatmapCard.cs | 6 +-- .../Drawables/Cards/BeatmapCardContent.cs | 52 +++++-------------- 2 files changed, 15 insertions(+), 43 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index 435a8227bd..2e39fafa05 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -284,7 +284,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards { Hovered = _ => { - content.ScheduleShow(); + content.ExpandAfterDelay(); return false; }, Unhovered = _ => @@ -292,7 +292,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards // This hide should only trigger if the expanded content has not shown yet. // ie. if the user has not shown intent to want to see it (quickly moved over the info row area). if (!Expanded.Value) - content.ScheduleHide(); + content.CollapseAfterDelay(); } } } @@ -368,7 +368,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards protected override void OnHoverLost(HoverLostEvent e) { - content.ScheduleHide(); + content.CollapseAfterDelay(); updateState(); base.OnHoverLost(e); diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs index e353e61b71..148372786a 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs @@ -56,7 +56,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards AutoSizeAxes = Axes.Y, CornerRadius = BeatmapCard.CORNER_RADIUS, Masking = true, - Unhovered = _ => checkForHide(), + Unhovered = _ => collapseIfNotHovered(), Children = new Drawable[] { background = new Box @@ -78,10 +78,10 @@ namespace osu.Game.Beatmaps.Drawables.Cards Alpha = 0, Hovered = _ => { - keep(); + queueExpandedStateChange(true); return true; }, - Unhovered = _ => checkForHide(), + Unhovered = _ => collapseIfNotHovered(), Child = dropdownScroll = new ExpandedContentScrollContainer { RelativeSizeAxes = Axes.X, @@ -121,51 +121,23 @@ namespace osu.Game.Beatmaps.Drawables.Cards private ScheduledDelegate? scheduledExpandedChange; - public void ScheduleShow() - { - scheduledExpandedChange?.Cancel(); - if (Expanded.Disabled || Expanded.Value) - return; + public void ExpandAfterDelay() => queueExpandedStateChange(true, 100); - scheduledExpandedChange = Scheduler.AddDelayed(() => - { - if (!Expanded.Disabled) - expanded.Value = true; - }, 100); + public void CollapseAfterDelay() => queueExpandedStateChange(false, 500); + + private void collapseIfNotHovered() + { + if (!content.IsHovered && !dropdownContent.IsHovered) + queueExpandedStateChange(false); } - public void ScheduleHide() - { - scheduledExpandedChange?.Cancel(); - if (Expanded.Disabled || !Expanded.Value) - return; - - scheduledExpandedChange = Scheduler.AddDelayed(() => - { - if (!Expanded.Disabled) - expanded.Value = false; - }, 500); - } - - private void checkForHide() - { - if (Expanded.Disabled) - return; - - if (content.IsHovered || dropdownContent.IsHovered) - return; - - scheduledExpandedChange?.Cancel(); - expanded.Value = false; - } - - private void keep() + private void queueExpandedStateChange(bool newState, int delay = 0) { if (Expanded.Disabled) return; scheduledExpandedChange?.Cancel(); - expanded.Value = true; + scheduledExpandedChange = Scheduler.AddDelayed(() => expanded.Value = newState, delay); } private void updateState() From 94d1a2aacae0a6472e06eeb004004a984feb69c4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Dec 2021 16:37:44 +0900 Subject: [PATCH 09/15] Remove unnecessary collapse call from `BeatmapCard` This is already handled at the `BeatmapCardContent` level. This call actually causes the buggy behaviour reported in https://github.com/ppy/osu/discussions/16085. --- osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index 2e39fafa05..be7119be36 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -368,8 +368,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards protected override void OnHoverLost(HoverLostEvent e) { - content.CollapseAfterDelay(); - updateState(); base.OnHoverLost(e); } From 6a1f535257c49720f9f81ca80d9942d44889456d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Dec 2021 16:38:19 +0900 Subject: [PATCH 10/15] Refactor cancellation of expand to be more explicit --- osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs | 6 +++--- osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index be7119be36..1e24501426 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -289,10 +289,10 @@ namespace osu.Game.Beatmaps.Drawables.Cards }, Unhovered = _ => { - // This hide should only trigger if the expanded content has not shown yet. - // ie. if the user has not shown intent to want to see it (quickly moved over the info row area). + // Handles the case where a user has not shown explicit intent to view expanded info. + // ie. quickly moved over the info row area but didn't remain within it. if (!Expanded.Value) - content.CollapseAfterDelay(); + content.CancelExpand(); } } } diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs index 148372786a..0739f7328f 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs @@ -123,7 +123,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards public void ExpandAfterDelay() => queueExpandedStateChange(true, 100); - public void CollapseAfterDelay() => queueExpandedStateChange(false, 500); + public void CancelExpand() => scheduledExpandedChange?.Cancel(); private void collapseIfNotHovered() { From ad430a627701afa2fcd7c538b99e232d4f54a693 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Dec 2021 16:44:58 +0900 Subject: [PATCH 11/15] Centralise hover state handling (and fix back-to-front conditionals) --- .../Beatmaps/Drawables/Cards/BeatmapCardContent.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs index 0739f7328f..286e03e700 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs @@ -56,7 +56,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards AutoSizeAxes = Axes.Y, CornerRadius = BeatmapCard.CORNER_RADIUS, Masking = true, - Unhovered = _ => collapseIfNotHovered(), + Unhovered = _ => updateFromHoverChange(), Children = new Drawable[] { background = new Box @@ -78,10 +78,10 @@ namespace osu.Game.Beatmaps.Drawables.Cards Alpha = 0, Hovered = _ => { - queueExpandedStateChange(true); + updateFromHoverChange(); return true; }, - Unhovered = _ => collapseIfNotHovered(), + Unhovered = _ => updateFromHoverChange(), Child = dropdownScroll = new ExpandedContentScrollContainer { RelativeSizeAxes = Axes.X, @@ -125,11 +125,8 @@ namespace osu.Game.Beatmaps.Drawables.Cards public void CancelExpand() => scheduledExpandedChange?.Cancel(); - private void collapseIfNotHovered() - { - if (!content.IsHovered && !dropdownContent.IsHovered) - queueExpandedStateChange(false); - } + private void updateFromHoverChange() => + queueExpandedStateChange(content.IsHovered || dropdownContent.IsHovered, 100); private void queueExpandedStateChange(bool newState, int delay = 0) { From c50206e25e285994df75c1927d5aa2889ce9d100 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Dec 2021 14:11:38 +0900 Subject: [PATCH 12/15] Update a few more public facing usages of "lazer" --- CONTRIBUTING.md | 8 ++++---- README.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e14be20642..ae2bdd2e82 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing Guidelines -Thank you for showing interest in the development of osu!lazer! We aim to provide a good collaborating environment for everyone involved, and as such have decided to list some of the most important things to keep in mind in the process. The guidelines below have been chosen based on past experience. +Thank you for showing interest in the development of osu!. We aim to provide a good collaborating environment for everyone involved, and as such have decided to list some of the most important things to keep in mind in the process. The guidelines below have been chosen based on past experience. These are not "official rules" *per se*, but following them will help everyone deal with things in the most efficient manner. @@ -32,7 +32,7 @@ Issues, bug reports and feature suggestions are welcomed, though please keep in * **Provide more information when asked to do so.** - Sometimes when a bug is more elusive or complicated, none of the information listed above will pinpoint a concrete cause of the problem. In this case we will most likely ask you for additional info, such as a Windows Event Log dump or a copy of your local lazer database (`client.db`). Providing that information is beneficial to both parties - we can track down the problem better, and hopefully fix it for you at some point once we know where it is! + Sometimes when a bug is more elusive or complicated, none of the information listed above will pinpoint a concrete cause of the problem. In this case we will most likely ask you for additional info, such as a Windows Event Log dump or a copy of your local osu! database (`client.db`). Providing that information is beneficial to both parties - we can track down the problem better, and hopefully fix it for you at some point once we know where it is! * **When submitting a feature proposal, please describe it in the most understandable way you can.** @@ -54,7 +54,7 @@ Issues, bug reports and feature suggestions are welcomed, though please keep in We also welcome pull requests from unaffiliated contributors. The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues that you can work on; we also mark issues that we think would be good for newcomers with the [`good-first-issue`](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue) label. -However, do keep in mind that the core team is committed to bringing osu!lazer up to par with stable first and foremost, so depending on what your contribution concerns, it might not be merged and released right away. Our approach to managing issues and their priorities is described [in the wiki](https://github.com/ppy/osu/wiki/Project-management). +However, do keep in mind that the core team is committed to bringing osu!(lazer) up to par with osu!(stable) first and foremost, so depending on what your contribution concerns, it might not be merged and released right away. Our approach to managing issues and their priorities is described [in the wiki](https://github.com/ppy/osu/wiki/Project-management). Here are some key things to note before jumping in: @@ -128,7 +128,7 @@ Here are some key things to note before jumping in: * **Don't mistake criticism of code for criticism of your person.** - As mentioned before, we are highly committed to quality when it comes to the lazer project. This means that contributions from less experienced community members can take multiple rounds of review to get to a mergeable state. We try our utmost best to never conflate a person with the code they authored, and to keep the discussion focused on the code at all times. Please consider our comments and requests a learning experience, and don't treat it as a personal attack. + As mentioned before, we are highly committed to quality when it comes to the osu! project. This means that contributions from less experienced community members can take multiple rounds of review to get to a mergeable state. We try our utmost best to never conflate a person with the code they authored, and to keep the discussion focused on the code at all times. Please consider our comments and requests a learning experience, and don't treat it as a personal attack. * **Feel free to reach out for help.** diff --git a/README.md b/README.md index 786ce2589d..24b70b2de6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ A free-to-win rhythm game. Rhythm is just a *click* away! -The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! Currently known by and released under the codename "*lazer*". As in sharper than cutting-edge. +The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! Currently known by and released under the release codename "*lazer*". As in sharper than cutting-edge. ## Status From 488374b4a27c56b0f26061d55e3f7648236e3354 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 16 Dec 2021 16:41:47 +0900 Subject: [PATCH 13/15] Don't show multiplayer channels in chat overlay --- .../Visual/Online/TestSceneChatOverlay.cs | 19 +++++++++++++++++++ osu.Game/Overlays/ChatOverlay.cs | 14 +++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 9c65b2dc51..14f32df653 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -393,6 +393,25 @@ namespace osu.Game.Tests.Visual.Online channelManager.CurrentChannel.Value.Type == ChannelType.PM && channelManager.CurrentChannel.Value.Users.Single().Username == "some body"); } + [Test] + public void TestMultiplayerChannelIsNotShown() + { + Channel multiplayerChannel = null; + + AddStep("join multiplayer channel", () => channelManager.JoinChannel(multiplayerChannel = new Channel(new APIUser()) + { + Name = "#mp_1", + Type = ChannelType.Multiplayer, + })); + + AddAssert("channel joined", () => channelManager.JoinedChannels.Contains(multiplayerChannel)); + AddAssert("channel not present in overlay", () => !chatOverlay.TabMap.ContainsKey(multiplayerChannel)); + AddAssert("multiplayer channel is not current", () => channelManager.CurrentChannel.Value != multiplayerChannel); + + AddStep("leave channel", () => channelManager.LeaveChannel(multiplayerChannel)); + AddAssert("channel left", () => !channelManager.JoinedChannels.Contains(multiplayerChannel)); + } + private void pressChannelHotkey(int number) { var channelKey = Key.Number0 + number; diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index cc3ce63bf7..72473d5750 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -237,10 +237,7 @@ namespace osu.Game.Overlays Schedule(() => { // TODO: consider scheduling bindable callbacks to not perform when overlay is not present. - channelManager.JoinedChannels.CollectionChanged += joinedChannelsChanged; - - foreach (Channel channel in channelManager.JoinedChannels) - ChannelTabControl.AddChannel(channel); + channelManager.JoinedChannels.BindCollectionChanged(joinedChannelsChanged, true); channelManager.AvailableChannels.CollectionChanged += availableChannelsChanged; availableChannelsChanged(null, null); @@ -436,12 +433,19 @@ namespace osu.Game.Overlays { case NotifyCollectionChangedAction.Add: foreach (Channel channel in args.NewItems.Cast()) - ChannelTabControl.AddChannel(channel); + { + if (channel.Type != ChannelType.Multiplayer) + ChannelTabControl.AddChannel(channel); + } + break; case NotifyCollectionChangedAction.Remove: foreach (Channel channel in args.OldItems.Cast()) { + if (!ChannelTabControl.Items.Contains(channel)) + continue; + ChannelTabControl.RemoveChannel(channel); var loaded = loadedChannels.Find(c => c.Channel == channel); From abb617a3df76c0ed685f9b84ae4abd4b3ea8be79 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Dec 2021 19:57:24 +0900 Subject: [PATCH 14/15] Avoid blocking `Active` state propagation --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index f5fc3de381..5c6b907e42 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; +using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Input.StateChanges.Events; @@ -44,8 +45,10 @@ namespace osu.Game.Rulesets.Osu { if (!AllowUserCursorMovement) { - // Still allow for forwarding of the "touch" part, but block the positional data. - e = new TouchStateChangeEvent(e.State, e.Input, e.Touch, false, null); + // Still allow for forwarding of the "touch" part, but replace the positional data with that of the mouse. + // Primarily relied upon by the "autopilot" osu! mod. + var touch = new Touch(e.Touch.Source, CurrentState.Mouse.Position); + e = new TouchStateChangeEvent(e.State, e.Input, touch, e.IsActive, null); } return base.HandleMouseTouchStateChange(e); From eecb1ce9f55084d19eea03378b9cf6c34cfe9706 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Dec 2021 20:20:02 +0900 Subject: [PATCH 15/15] Avoid applying mouse down effects to menu cursor when it isn't visible Closes #16114. --- osu.Game/Graphics/Cursor/MenuCursor.cs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 3fa90e2330..8e272f637f 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -72,18 +72,21 @@ namespace osu.Game.Graphics.Cursor protected override bool OnMouseDown(MouseDownEvent e) { - // only trigger animation for main mouse buttons - activeCursor.Scale = new Vector2(1); - activeCursor.ScaleTo(0.90f, 800, Easing.OutQuint); - - activeCursor.AdditiveLayer.Alpha = 0; - activeCursor.AdditiveLayer.FadeInFromZero(800, Easing.OutQuint); - - if (cursorRotate.Value && dragRotationState != DragRotationState.Rotating) + if (State.Value == Visibility.Visible) { - // if cursor is already rotating don't reset its rotate origin - dragRotationState = DragRotationState.DragStarted; - positionMouseDown = e.MousePosition; + // only trigger animation for main mouse buttons + activeCursor.Scale = new Vector2(1); + activeCursor.ScaleTo(0.90f, 800, Easing.OutQuint); + + activeCursor.AdditiveLayer.Alpha = 0; + activeCursor.AdditiveLayer.FadeInFromZero(800, Easing.OutQuint); + + if (cursorRotate.Value && dragRotationState != DragRotationState.Rotating) + { + // if cursor is already rotating don't reset its rotate origin + dragRotationState = DragRotationState.DragStarted; + positionMouseDown = e.MousePosition; + } } return base.OnMouseDown(e);