This PR refactors the report popover to have an optional confirmation
message after completing the request. This was initially meant for
#32584, but then I realized I can first test it out on the user
profiles, so I've implemented it here as well. Can be reviewed commit by
commit.
https://github.com/user-attachments/assets/cd59c560-c824-4a5e-bab6-5ecbf5125af1
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
This was a private request for roundtable event usage. It’s also a
common feature request, so I decided to spend a bit of time getting this
working well-enough.
https://github.com/user-attachments/assets/acceb57f-2979-43d0-9fc2-33e977bd2dd5
---
### Delay loading spinner / loading layer initial load briefly to avoid
flickering
There's cases in this overlay where loading takes a few milliseconds.
The loading spinner gets annoying. This also happens elsewhere, so this
could be considered a global fix. Separate PR? probably...
### Ingest loading state of dashboard child content to show more correct
loading layer
Each display had their own loading layer implementation, but this is
already too deep (inside the scroll content) and doesn't display great
when for instance, results don't take up the full screen height.
---------
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
Specifically the one used on the daily challenge screen. Was bugging me
that playlists/multi have that old yellow header design used, so I've
changed it. Will probably come in handy once the footer/leaderboard
changes are in.
Also localized the headers while at it.
Multiplayer:

Playlists:

The only thing I'm wondering about is whether the detail thing
(participant count/playlist length) should be using the highlight colour
here. The old design had them be yellow, but I feel like the pink on
this one stands out too much.
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
TL;DR the clock was being set too late, causing more transforms to be
created than necessary.
This solves the issue by way of a refactor (sorry). Overall this should
simplify handling of things as more of the logic is shared with the
known good-state `BeatmapBackgroundWithStoryboard`.
I did try without a refactor (just delaying the creation until the clock
arrives) but this version made more sense because background generally
expect to do their main load in BDL to aid in smooth transitions. And we
can't get the clock by there. (although arguably we could just use a
similar method to `BeatmapBackgroundWithStoryboard` and forego using the
editor clock).
Of note, I removed the black background overdraw hack. There are edge
cases where it will lead to weird transitions, but these are far and few
between. Basically you need a storyboard which sets the flag to hide the
beatmap background and has transparency in it. This is no longer as
flagrantly bad as things used to be (which led to the inline fix) as far
as I can tell, but feel free to prove me wrong. If this is a blocker
I'll probably just add a permanent black box (which does fix this).
Closes#36875.
Right click is a very obfuscated UX which most users won't find. This
makes more sense to the average user (probably).
Caveat: clicking away actually sends clicks to underlying UI. This is
not the case in macOS or windows (locally, same app; globally it still
sends clicks to other windows).
Coming from https://github.com/ppy/osu/discussions/36926.
---------
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
As [per
comment](https://github.com/ppy/osu/pull/36943#issuecomment-4045361755).
Unfortunately I'm not able to reproduce such a big impact of triangles
using linked pr (or at all really). In my case usage was low in the
first place and went from 0.9% to 0.6% with this pr, so outside
benchmarking would be great
Improvement list:
* No more sorted list. Basic list is being used which is sorted once
after all the triangles added.
* Out-of-bounds triangles are reused rather than removed and re-added.
* On `Reset` if `AimCount` stays the same, all triangles are reused
instead of being cleared and re-added.
This commit rearranges the contents of `ShearedButtons` to be more
independent of each other in regards to sizing. Thanks to that, the
custom logic related to enabling autosizing is no longer necessary.
Witdh and height are no longer set via the constructor, and can be
freely configured using the initializer syntax.
Additionally, this allows the button to use relative sizing without
having to resort to any hackery with `Size` (this will come in handy for
me when implementing the new footer on multiplayer screens).
Given that most of the `ShearedButton`s currently in use set their width
explicitly, I did not set `AutoSizeAxes = Axes.X` like it would be by
default previously. Instead it is set on the only two such buttons (show
converts/selected mods on ssv2). I suppose it might be a good idea to
have it set that by default if no `Width` is specified, as right now
it'll just not show anything.
Also I've set the margin on the text field by default in all cases
instead of only when autosizing like how it was previously, since
otherwise it would be a pain to set that on each button instance when
needed. I've checked all affected components and could not find any text
overflowing issues that this could cause.
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>
Resolves#36099
This PR fixes keyboard navigation in the beatmap select carousel for
lazer by implementing page-wise traversal with the Page Up and Page Down
keys and changing it from only scrolling to actually selecting items.
**Changes:**
- Added handling for `TraversalType.Page` in the keyboard traversal
switch.
- Implemented `traverseKeyboardPage(int direction)` method to move the
selection by approximately one "page" of visible items, accounting for
partially obscured items like the search bar. Also it does not wrap
around (like the current PageUp/Down functionality).
- Added new key bindings:
- `PageUp` → SelectPreviousPage
- `PageDown` → SelectNextPage
The code may be very explicit for the scroll logic with the page keys,
so I would appreciate some feedback when the PR is reviewed.
The naming of the keybinds may need to be adjusted. `Next page` and
`previous page` may be somewhat misleading.
**Behavior after the change:**
- Pressing Page Up/Down now moves the selection by a page of items.
- After navigating, pressing Left/Right selects the navigated song
instead of moving relative to the previous position.
**See:**
https://www.youtube.com/watch?v=JXmKAhhKiCc
---------
Signed-off-by: Linus Genz <linuslinuxgenz@gmail.com>
Co-authored-by: Dean Herbert <pe@ppy.sh>
Regressed in d6bf4fd90d.
One very visible instance of this regression is the login form.
https://github.com/user-attachments/assets/5ba10ac5-4cb1-49af-b55c-89cf58ca0b44
The `CommentEditor` usage was discovered with one of my favourite tricks
which is doing
```diff
diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs
index fefe776b01..c17cca726b 100644
--- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs
+++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs
@@ -42,6 +42,12 @@ public partial class OsuTextBox : BasicTextBox
Margin = new MarginPadding { Left = 2 },
};
+ public new bool Masking
+ {
+ get => base.Masking;
+ set => base.Masking = value;
+ }
+
protected bool DrawBorder { get; init; } = true;
private OsuCaret? caret;
```
and then looking for usages of the setter. That's all due diligence
you're getting here, I'm not auditing every single text box in the game.
And yes, the `CommentEditor` usage is OMEGA dodgy but the change applied
here is the only one that preserves its visual appearance. I'm not
putting in time to fix it.
This removes the disabled sound, but I think that's fine. If we want
that, it should be handled by `HoverClickSounds` (which I'm currently
intentionally not using because it can be a bit noisy).
Closes#36503.
This was attempted to be fixed by frenzibyte using some hack workaround
logic, but this is the true fix.
Things were never matching due to `UpdateSize` spamming `Resize`
transforms every frame, causing the fade out to complete before
transforms have reached a final state.
See inline commentary. I don't really have any energy left to provide
anything else, other than maybe a demonstration of how this dies in
framework:
diff --git a/osu.Framework.Tests/Visual/UserInterface/TestSceneScreenStackUnbindOnExit.cs b/osu.Framework.Tests/Visual/UserInterface/TestSceneScreenStackUnbindOnExit.cs
new file mode 100644
index 000000000..c74ce6636
--- /dev/null
+++ b/osu.Framework.Tests/Visual/UserInterface/TestSceneScreenStackUnbindOnExit.cs
@@ -0,0 +1,59 @@
+// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics.UserInterface;
+using osu.Framework.Screens;
+
+namespace osu.Framework.Tests.Visual.UserInterface
+{
+ public partial class TestSceneScreenStackUnbindOnExit : FrameworkTestScene
+ {
+ [Cached]
+ private ScreenStack screenStack = new ScreenStack();
+
+ [Test]
+ public void TestScreenExitUnbindDoesNotInterruptLoadComplete()
+ {
+ AddStep("set up the scenario", () =>
+ {
+ Child = screenStack;
+ screenStack.Push(new Screen());
+ screenStack.Push(new BrokenScreen());
+ });
+ AddUntilStep("wait to get to target screen", () => screenStack.CurrentScreen, Is.InstanceOf<Screen>);
+ }
+
+ private partial class BrokenSlider : BasicSliderBar<float>
+ {
+ [Resolved]
+ private ScreenStack screenStack { get; set; } = null!;
+
+ protected override void LoadComplete()
+ {
+ // exiting the current screen provokes the behaviour of unbinding all bindables in the screen's subtree
+ screenStack.CurrentScreen.Exit();
+
+ // ...but the following calls should still take correct effect inside `SliderBar`
+ // (namely one consisting of propagating `{Min,Max}Value` into `currentNumberInstantaneous`)
+ // so that it doesn't have its internal invariants violated
+ CurrentNumber.MinValue = -10;
+ CurrentNumber.MaxValue = 10;
+
+ // this notably calls `Scheduler.AddOnce(updateValue)` inside, which will happen *in the imminent future, in the same frame as `LoadComplete()` here.
+ // if the above mutations of `{Min,Max}Value` don't correctly propagate inside the slider bar due to an overly eager unbind, this will cause a crash.
+ base.LoadComplete();
+ }
+ }
+
+ private partial class BrokenScreen : Screen
+ {
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ InternalChild = new BrokenSlider();
+ }
+ }
+ }
+}
I attempted to address what I perceive to be the root issue here which
is that `ScreenStack` is allowed to arbitrarily unbind bindables under
drawables which are by all means still in the scene graph. The attempt
consisted of scheduling the unbind until after children of the screen
stack, but that caused 150 game-side tests to fail, seemingly on
something relevant to bindable leases, so I give up.