1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-19 18:22:59 +08:00

Merge branch 'master' into distance-snap-grid-current-tiume

This commit is contained in:
Bartłomiej Dach 2022-05-07 08:49:30 +02:00 committed by GitHub
commit 202a603d72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 331 additions and 223 deletions

View File

@ -2,12 +2,6 @@
"version": 1, "version": 1,
"isRoot": true, "isRoot": true,
"tools": { "tools": {
"dotnet-format": {
"version": "3.1.37601",
"commands": [
"dotnet-format"
]
},
"jetbrains.resharper.globaltools": { "jetbrains.resharper.globaltools": {
"version": "2022.1.0-eap10", "version": "2022.1.0-eap10",
"commands": [ "commands": [

View File

@ -1,6 +1,14 @@
# EditorConfig is awesome: http://editorconfig.org # EditorConfig is awesome: http://editorconfig.org
root = true root = true
[*.{csproj,props,targets}]
charset = utf-8-bom
end_of_line = crlf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
[*.cs] [*.cs]
end_of_line = crlf end_of_line = crlf
insert_final_newline = true insert_final_newline = true
@ -8,8 +16,19 @@ indent_style = space
indent_size = 4 indent_size = 4
trim_trailing_whitespace = true trim_trailing_whitespace = true
#license header
file_header_template = Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\nSee the LICENCE file in the repository root for full licence text.
#Roslyn naming styles #Roslyn naming styles
#PascalCase for public and protected members
dotnet_naming_style.pascalcase.capitalization = pascal_case
dotnet_naming_symbols.public_members.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
dotnet_naming_symbols.public_members.applicable_kinds = property,method,field,event
dotnet_naming_rule.public_members_pascalcase.severity = error
dotnet_naming_rule.public_members_pascalcase.symbols = public_members
dotnet_naming_rule.public_members_pascalcase.style = pascalcase
#camelCase for private members #camelCase for private members
dotnet_naming_style.camelcase.capitalization = camel_case dotnet_naming_style.camelcase.capitalization = camel_case
@ -172,24 +191,11 @@ csharp_style_prefer_index_operator = false:silent
csharp_style_prefer_range_operator = false:silent csharp_style_prefer_range_operator = false:silent
csharp_style_prefer_switch_expression = false:none csharp_style_prefer_switch_expression = false:none
#Supressing roslyn built-in analyzers [*.{yaml,yml}]
# Suppress: EC112 insert_final_newline = true
indent_style = space
#Private method is unused indent_size = 2
dotnet_diagnostic.IDE0051.severity = silent trim_trailing_whitespace = true
#Private member is unused
dotnet_diagnostic.IDE0052.severity = silent
#Rules for disposable
dotnet_diagnostic.IDE0067.severity = none
dotnet_diagnostic.IDE0068.severity = none
dotnet_diagnostic.IDE0069.severity = none
#Disable operator overloads requiring alternate named methods
dotnet_diagnostic.CA2225.severity = none
# Banned APIs
dotnet_diagnostic.RS0030.severity = error
dotnet_diagnostic.OLOC001.words_in_name = 5 dotnet_diagnostic.OLOC001.words_in_name = 5
dotnet_diagnostic.OLOC001.license_header = // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\n// See the LICENCE file in the repository root for full licence text. dotnet_diagnostic.OLOC001.license_header = // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\n// See the LICENCE file in the repository root for full licence text.

View File

@ -33,6 +33,9 @@ jobs:
path: ${{ github.workspace }}/inspectcode path: ${{ github.workspace }}/inspectcode
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json') }}-${{ hashFiles('.github/workflows/ci.yml' ) }} key: inspectcode-${{ hashFiles('.config/dotnet-tools.json') }}-${{ hashFiles('.github/workflows/ci.yml' ) }}
- name: Dotnet code style
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf -p:EnforceCodeStyleInBuild=true
- name: CodeFileSanity - name: CodeFileSanity
run: | run: |
# TODO: Add ignore filters and GitHub Workflow Command Reporting in CFS. That way we don't have to do this workaround. # TODO: Add ignore filters and GitHub Workflow Command Reporting in CFS. That way we don't have to do this workaround.
@ -46,10 +49,6 @@ jobs:
done <<< $(dotnet codefilesanity) done <<< $(dotnet codefilesanity)
exit $exit_code exit $exit_code
# Temporarily disabled due to test failures, but it won't work anyway until the tool is upgraded.
# - name: .NET Format (Dry Run)
# run: dotnet format --dry-run --check
- name: InspectCode - name: InspectCode
run: dotnet jb inspectcode $(pwd)/osu.Desktop.slnf --no-build --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN run: dotnet jb inspectcode $(pwd)/osu.Desktop.slnf --no-build --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN
@ -147,4 +146,4 @@ jobs:
# cannot accept .sln(f) files as arguments. # cannot accept .sln(f) files as arguments.
# Build just the main game for now. # Build just the main game for now.
- name: Build - name: Build
run: msbuild osu.iOS/osu.iOS.csproj /restore /p:Configuration=Debug run: msbuild osu.iOS/osu.iOS.csproj /restore /p:Configuration=Debug

55
.globalconfig Normal file
View File

@ -0,0 +1,55 @@
is_global = true
# .NET Code Style
# IDE styles reference: https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/
# IDE0001: Simplify names
dotnet_diagnostic.IDE0001.severity = warning
# IDE0002: Simplify member access
dotnet_diagnostic.IDE0002.severity = warning
# IDE0003: Remove qualification
dotnet_diagnostic.IDE0003.severity = warning
# IDE0004: Remove unnecessary cast
dotnet_diagnostic.IDE0004.severity = warning
# IDE0005: Remove unnecessary imports
dotnet_diagnostic.IDE0005.severity = warning
# IDE0034: Simplify default literal
dotnet_diagnostic.IDE0034.severity = warning
# IDE0036: Sort modifiers
dotnet_diagnostic.IDE0036.severity = warning
# IDE0040: Add accessibility modifier
dotnet_diagnostic.IDE0040.severity = warning
# IDE0049: Use keyword for type name
dotnet_diagnostic.IDE0040.severity = warning
# IDE0055: Fix formatting
dotnet_diagnostic.IDE0055.severity = warning
# IDE0051: Private method is unused
dotnet_diagnostic.IDE0051.severity = silent
# IDE0052: Private member is unused
dotnet_diagnostic.IDE0052.severity = silent
# IDE0073: File header
dotnet_diagnostic.IDE0073.severity = warning
# IDE0130: Namespace mismatch with folder
dotnet_diagnostic.IDE0130.severity = warning
# IDE1006: Naming style
dotnet_diagnostic.IDE1006.severity = warning
#Disable operator overloads requiring alternate named methods
dotnet_diagnostic.CA2225.severity = none
# Banned APIs
dotnet_diagnostic.RS0030.severity = error

View File

@ -1,4 +1,4 @@
<!-- Contains required properties for osu!framework projects. --> <!-- Contains required properties for osu!framework projects. -->
<Project> <Project>
<PropertyGroup Label="C#"> <PropertyGroup Label="C#">
<LangVersion>8.0</LangVersion> <LangVersion>8.0</LangVersion>

View File

@ -1,4 +1,4 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<LangVersion>8.0</LangVersion> <LangVersion>8.0</LangVersion>
<OutputPath>bin\$(Configuration)</OutputPath> <OutputPath>bin\$(Configuration)</OutputPath>

View File

@ -29,13 +29,14 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
protected CatchSelectionBlueprintTestScene() protected CatchSelectionBlueprintTestScene()
{ {
EditorBeatmap = new EditorBeatmap(new CatchBeatmap var catchBeatmap = new CatchBeatmap
{ {
BeatmapInfo = BeatmapInfo =
{ {
Ruleset = new CatchRuleset().RulesetInfo, Ruleset = new CatchRuleset().RulesetInfo,
} }
}) { Difficulty = { CircleSize = 0 } }; };
EditorBeatmap = new EditorBeatmap(catchBeatmap) { Difficulty = { CircleSize = 0 } };
EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint
{ {
BeatLength = 100 BeatLength = 100

View File

@ -142,13 +142,12 @@ namespace osu.Game.Tests.Visual.Collections
AddStep("add dropdown", () => AddStep("add dropdown", () =>
{ {
Add(new CollectionFilterDropdown Add(new CollectionFilterDropdown
{ {
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Width = 0.4f, Width = 0.4f,
} });
);
}); });
AddStep("add two collections with same name", () => manager.Collections.AddRange(new[] AddStep("add two collections with same name", () => manager.Collections.AddRange(new[]
{ {

View File

@ -6,24 +6,19 @@ using NUnit.Framework;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.OnlinePlay; using osu.Game.Screens.OnlinePlay;
namespace osu.Game.Tests.Visual.Multiplayer namespace osu.Game.Tests.Visual.Multiplayer
{ {
public class TestSceneFreeModSelectScreen : MultiplayerTestScene public class TestSceneFreeModSelectScreen : MultiplayerTestScene
{ {
private FreeModSelectScreen freeModSelectScreen;
[Test] [Test]
public void TestFreeModSelect() public void TestFreeModSelect()
{ {
FreeModSelectScreen freeModSelectScreen = null; createFreeModSelect();
AddStep("create free mod select screen", () => Child = freeModSelectScreen = new FreeModSelectScreen
{
State = { Value = Visibility.Visible }
});
AddUntilStep("all column content loaded",
() => freeModSelectScreen.ChildrenOfType<ModColumn>().Any()
&& freeModSelectScreen.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
AddUntilStep("all visible mods are playable", AddUntilStep("all visible mods are playable",
() => this.ChildrenOfType<ModPanel>() () => this.ChildrenOfType<ModPanel>()
@ -36,5 +31,26 @@ namespace osu.Game.Tests.Visual.Multiplayer
freeModSelectScreen.State.Value = visible ? Visibility.Visible : Visibility.Hidden; freeModSelectScreen.State.Value = visible ? Visibility.Visible : Visibility.Hidden;
}); });
} }
[Test]
public void TestCustomisationNotAvailable()
{
createFreeModSelect();
AddStep("select difficulty adjust", () => freeModSelectScreen.SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
AddWaitStep("wait some", 3);
AddAssert("customisation area not expanded", () => this.ChildrenOfType<ModSettingsArea>().Single().Height == 0);
}
private void createFreeModSelect()
{
AddStep("create free mod select screen", () => Child = freeModSelectScreen = new FreeModSelectScreen
{
State = { Value = Visibility.Visible }
});
AddUntilStep("all column content loaded",
() => freeModSelectScreen.ChildrenOfType<ModColumn>().Any()
&& freeModSelectScreen.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
}
} }
} }

View File

@ -99,15 +99,15 @@ namespace osu.Game.Tests.Visual.UserInterface
} }
/// <summary> /// <summary>
/// Tests expanding a container will expand underlying groups if contracted. /// Tests expanding a container will not expand underlying groups if they were manually contracted by the user.
/// </summary> /// </summary>
[Test] [Test]
public void TestExpandingContainerExpandsContractedGroup() public void TestExpandingContainerDoesNotExpandContractedGroup()
{ {
AddStep("contract group", () => toolboxGroup.Expanded.Value = false); AddStep("contract group", () => toolboxGroup.Expanded.Value = false);
AddStep("expand container", () => container.Expanded.Value = true); AddStep("expand container", () => container.Expanded.Value = true);
AddAssert("group expanded", () => toolboxGroup.Expanded.Value); AddAssert("group not expanded", () => !toolboxGroup.Expanded.Value);
AddAssert("controls expanded", () => slider1.Expanded.Value && slider2.Expanded.Value); AddAssert("controls expanded", () => slider1.Expanded.Value && slider2.Expanded.Value);
AddStep("contract container", () => container.Expanded.Value = false); AddStep("contract container", () => container.Expanded.Value = false);

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Input.Bindings; using osu.Game.Input.Bindings;

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,6 +1,7 @@
using System; // 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 Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using System.IO;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using System; // 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 System;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using System; // 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 System;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1,4 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; // 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 Microsoft.EntityFrameworkCore.Migrations;
namespace osu.Game.Migrations namespace osu.Game.Migrations
{ {

View File

@ -1153,6 +1153,7 @@ namespace osu.Game
horizontalOffset += (Content.ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - Content.DrawWidth) * SIDE_OVERLAY_OFFSET_RATIO; horizontalOffset += (Content.ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - Content.DrawWidth) * SIDE_OVERLAY_OFFSET_RATIO;
ScreenOffsetContainer.X = horizontalOffset; ScreenOffsetContainer.X = horizontalOffset;
overlayContent.X = horizontalOffset * 1.2f;
MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false;
} }

View File

@ -119,7 +119,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
maxComboColumn.Text = value.MaxCombo.ToLocalisableString(@"0\x"); maxComboColumn.Text = value.MaxCombo.ToLocalisableString(@"0\x");
ppColumn.Alpha = value.BeatmapInfo.Status.GrantsPerformancePoints() ? 1 : 0; ppColumn.Alpha = value.BeatmapInfo.Status.GrantsPerformancePoints() ? 1 : 0;
ppColumn.Text = value.PP?.ToLocalisableString(@"N0") ?? default(LocalisableString); ppColumn.Text = value.PP?.ToLocalisableString(@"N0") ?? default;
statisticsColumns.ChildrenEnumerable = value.GetStatisticsForDisplay().Select(createStatisticsColumn); statisticsColumns.ChildrenEnumerable = value.GetStatisticsForDisplay().Select(createStatisticsColumn);
modsColumn.Mods = value.Mods; modsColumn.Mods = value.Mods;

View File

@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Mods
set set
{ {
filter = value; filter = value;
updateFilter(); updateState();
} }
} }
@ -292,9 +292,7 @@ namespace osu.Game.Overlays.Mods
{ {
panelFlow.ChildrenEnumerable = loaded; panelFlow.ChildrenEnumerable = loaded;
updateActiveState(); updateState();
updateToggleAllState();
updateFilter();
foreach (var panel in panelFlow) foreach (var panel in panelFlow)
{ {
@ -308,10 +306,19 @@ namespace osu.Game.Overlays.Mods
}); });
} }
private void updateActiveState() private void updateState()
{ {
foreach (var panel in panelFlow) foreach (var panel in panelFlow)
{
panel.Active.Value = SelectedMods.Contains(panel.Mod); panel.Active.Value = SelectedMods.Contains(panel.Mod);
panel.ApplyFilter(Filter);
}
if (toggleAllCheckbox != null && !SelectionAnimationRunning)
{
toggleAllCheckbox.Alpha = panelFlow.Any(panel => !panel.Filtered.Value) ? 1 : 0;
toggleAllCheckbox.Current.Value = panelFlow.Where(panel => !panel.Filtered.Value).All(panel => panel.Active.Value);
}
} }
/// <summary> /// <summary>
@ -323,15 +330,16 @@ namespace osu.Game.Overlays.Mods
private void panelStateChanged(ModPanel panel) private void panelStateChanged(ModPanel panel)
{ {
updateToggleAllState(); if (externalSelectionUpdateInProgress)
return;
var newSelectedMods = panel.Active.Value var newSelectedMods = panel.Active.Value
? SelectedMods.Append(panel.Mod) ? SelectedMods.Append(panel.Mod)
: SelectedMods.Except(panel.Mod.Yield()); : SelectedMods.Except(panel.Mod.Yield());
SelectedMods = newSelectedMods.ToArray(); SelectedMods = newSelectedMods.ToArray();
if (!externalSelectionUpdateInProgress) updateState();
SelectionChangedByUser?.Invoke(); SelectionChangedByUser?.Invoke();
} }
/// <summary> /// <summary>
@ -364,7 +372,7 @@ namespace osu.Game.Overlays.Mods
} }
SelectedMods = newSelection; SelectedMods = newSelection;
updateActiveState(); updateState();
externalSelectionUpdateInProgress = false; externalSelectionUpdateInProgress = false;
} }
@ -403,15 +411,6 @@ namespace osu.Game.Overlays.Mods
} }
} }
private void updateToggleAllState()
{
if (toggleAllCheckbox != null && !SelectionAnimationRunning)
{
toggleAllCheckbox.Alpha = panelFlow.Any(panel => !panel.Filtered.Value) ? 1 : 0;
toggleAllCheckbox.Current.Value = panelFlow.Where(panel => !panel.Filtered.Value).All(panel => panel.Active.Value);
}
}
/// <summary> /// <summary>
/// Selects all mods. /// Selects all mods.
/// </summary> /// </summary>
@ -507,18 +506,6 @@ namespace osu.Game.Overlays.Mods
#endregion #endregion
#region Filtering support
private void updateFilter()
{
foreach (var modPanel in panelFlow)
modPanel.ApplyFilter(Filter);
updateToggleAllState();
}
#endregion
#region Keyboard selection support #region Keyboard selection support
protected override bool OnKeyDown(KeyDownEvent e) protected override bool OnKeyDown(KeyDownEvent e)

View File

@ -13,6 +13,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Layout; using osu.Framework.Layout;
using osu.Framework.Lists;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -264,7 +265,9 @@ namespace osu.Game.Overlays.Mods
{ {
var candidateSelection = columnFlow.Columns.SelectMany(column => column.SelectedMods).ToArray(); var candidateSelection = columnFlow.Columns.SelectMany(column => column.SelectedMods).ToArray();
if (candidateSelection.SequenceEqual(SelectedMods.Value)) // the following guard intends to check cases where we've already replaced potentially-external mod references with our own and avoid endless recursion.
// TODO: replace custom comparer with System.Collections.Generic.ReferenceEqualityComparer when fully on .NET 6
if (candidateSelection.SequenceEqual(SelectedMods.Value, new FuncEqualityComparer<Mod>(ReferenceEquals)))
return; return;
SelectedMods.Value = ComputeNewModsFromSelection(SelectedMods.Value, candidateSelection); SelectedMods.Value = ComputeNewModsFromSelection(SelectedMods.Value, candidateSelection);

View File

@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
private void updateProgress(APIUser user) private void updateProgress(APIUser user)
{ {
levelProgressBar.Length = user?.Statistics?.Level.Progress / 100f ?? 0; levelProgressBar.Length = user?.Statistics?.Level.Progress / 100f ?? 0;
levelProgressText.Text = user?.Statistics?.Level.Progress.ToLocalisableString("0'%'") ?? default(LocalisableString); levelProgressText.Text = user?.Statistics?.Level.Progress.ToLocalisableString("0'%'") ?? default;
} }
} }
} }

View File

@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Rankings
startDateColumn.Value = dateToString(response.Spotlight.StartDate); startDateColumn.Value = dateToString(response.Spotlight.StartDate);
endDateColumn.Value = dateToString(response.Spotlight.EndDate); endDateColumn.Value = dateToString(response.Spotlight.EndDate);
mapCountColumn.Value = response.BeatmapSets.Count.ToLocalisableString(@"N0"); mapCountColumn.Value = response.BeatmapSets.Count.ToLocalisableString(@"N0");
participantsColumn.Value = response.Spotlight.Participants?.ToLocalisableString(@"N0") ?? default(LocalisableString); participantsColumn.Value = response.Spotlight.Participants?.ToLocalisableString(@"N0") ?? default;
} }
private LocalisableString dateToString(DateTimeOffset date) => date.ToLocalisableString(@"yyyy-MM-dd"); private LocalisableString dateToString(DateTimeOffset date) => date.ToLocalisableString(@"yyyy-MM-dd");

View File

@ -5,7 +5,6 @@ using System.Collections.Generic;
using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Localisation;
using osu.Game.Resources.Localisation.Web; using osu.Game.Resources.Localisation.Web;
using osu.Game.Users; using osu.Game.Users;
@ -25,7 +24,7 @@ namespace osu.Game.Overlays.Rankings.Tables
protected override Drawable[] CreateUniqueContent(UserStatistics item) => new Drawable[] protected override Drawable[] CreateUniqueContent(UserStatistics item) => new Drawable[]
{ {
new RowText { Text = item.PP?.ToLocalisableString(@"N0") ?? default(LocalisableString), } new RowText { Text = item.PP?.ToLocalisableString(@"N0") ?? default, }
}; };
} }
} }

View File

@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Caching; using osu.Framework.Caching;
using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Extensions.EnumExtensions;
@ -35,14 +34,13 @@ namespace osu.Game.Overlays
private readonly Cached headerTextVisibilityCache = new Cached(); private readonly Cached headerTextVisibilityCache = new Cached();
private readonly FillFlowContainer content; private readonly FillFlowContainer content;
private readonly IconButton button;
public BindableBool Expanded { get; } = new BindableBool(true); public BindableBool Expanded { get; } = new BindableBool(true);
private Color4 expandedColour;
private readonly OsuSpriteText headerText; private readonly OsuSpriteText headerText;
private readonly Container headerContent;
/// <summary> /// <summary>
/// Create a new instance. /// Create a new instance.
/// </summary> /// </summary>
@ -71,7 +69,7 @@ namespace osu.Game.Overlays
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Children = new Drawable[] Children = new Drawable[]
{ {
new Container headerContent = new Container
{ {
Name = @"Header", Name = @"Header",
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
@ -88,7 +86,7 @@ namespace osu.Game.Overlays
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17), Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17),
Padding = new MarginPadding { Left = 10, Right = 30 }, Padding = new MarginPadding { Left = 10, Right = 30 },
}, },
button = new IconButton new IconButton
{ {
Origin = Anchor.Centre, Origin = Anchor.Centre,
Anchor = Anchor.CentreRight, Anchor = Anchor.CentreRight,
@ -117,12 +115,25 @@ namespace osu.Game.Overlays
}; };
} }
protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source) protected override void LoadComplete()
{ {
if (invalidation.HasFlagFast(Invalidation.DrawSize)) base.LoadComplete();
headerTextVisibilityCache.Invalidate();
return base.OnInvalidate(invalidation, source); Expanded.BindValueChanged(updateExpandedState, true);
this.Delay(600).Schedule(updateFadeState);
}
protected override bool OnHover(HoverEvent e)
{
updateFadeState();
return false;
}
protected override void OnHoverLost(HoverLostEvent e)
{
updateFadeState();
base.OnHoverLost(e);
} }
protected override void Update() protected override void Update()
@ -135,72 +146,30 @@ namespace osu.Game.Overlays
headerText.FadeTo(headerText.DrawWidth < DrawWidth ? 1 : 0, 150, Easing.OutQuint); headerText.FadeTo(headerText.DrawWidth < DrawWidth ? 1 : 0, 150, Easing.OutQuint);
} }
[Resolved(canBeNull: true)] protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source)
private IExpandingContainer expandingContainer { get; set; }
private bool expandedByContainer;
protected override void LoadComplete()
{ {
base.LoadComplete(); if (invalidation.HasFlagFast(Invalidation.DrawSize))
headerTextVisibilityCache.Invalidate();
expandingContainer?.Expanded.BindValueChanged(containerExpanded => return base.OnInvalidate(invalidation, source);
}
private void updateExpandedState(ValueChangedEvent<bool> expanded)
{
if (expanded.NewValue)
content.AutoSizeAxes = Axes.Y;
else
{ {
if (containerExpanded.NewValue && !Expanded.Value) content.AutoSizeAxes = Axes.None;
{ content.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
Expanded.Value = true; }
expandedByContainer = true;
}
else if (!containerExpanded.NewValue && expandedByContainer)
{
Expanded.Value = false;
expandedByContainer = false;
}
updateActiveState(); headerContent.FadeColour(expanded.NewValue ? Color4.White : OsuColour.Gray(0.5f), 200, Easing.OutQuint);
}, true);
Expanded.BindValueChanged(v =>
{
// clearing transforms can break autosizing, see: https://github.com/ppy/osu-framework/issues/5064
if (v.NewValue != v.OldValue)
content.ClearTransforms();
if (v.NewValue)
content.AutoSizeAxes = Axes.Y;
else
{
content.AutoSizeAxes = Axes.None;
content.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
}
button.FadeColour(Expanded.Value ? expandedColour : Color4.White, 200, Easing.InOutQuint);
}, true);
this.Delay(600).Schedule(updateActiveState);
} }
protected override bool OnHover(HoverEvent e) private void updateFadeState()
{ {
updateActiveState(); this.FadeTo(IsHovered ? 1 : inactive_alpha, fade_duration, Easing.OutQuint);
return false;
}
protected override void OnHoverLost(HoverLostEvent e)
{
updateActiveState();
base.OnHoverLost(e);
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
expandedColour = colours.Yellow;
}
private void updateActiveState()
{
this.FadeTo(IsHovered || expandingContainer?.Expanded.Value == true ? 1 : inactive_alpha, fade_duration, Easing.OutQuint);
} }
protected override Container<Drawable> Content => content; protected override Container<Drawable> Content => content;

View File

@ -100,7 +100,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void updateTooltipText() private void updateTooltipText()
{ {
TooltipText = cumulativeRotation.Value?.ToLocalisableString("0.0°") ?? default(LocalisableString); TooltipText = cumulativeRotation.Value?.ToLocalisableString("0.0°") ?? default;
} }
} }
} }

View File

@ -87,44 +87,46 @@ namespace osu.Game.Screens.OnlinePlay.Components
}, },
}; };
// case MatchType.TagCoop: #pragma warning disable IDE0055 // Indentation of commented code
// return new SpriteIcon // case MatchType.TagCoop:
// { // return new SpriteIcon
// Anchor = Anchor.Centre, // {
// Origin = Anchor.Centre, // Anchor = Anchor.Centre,
// Size = new Vector2(size), // Origin = Anchor.Centre,
// Icon = FontAwesome.Solid.Sync, // Size = new Vector2(size),
// Colour = colours.Blue, // Icon = FontAwesome.Solid.Sync,
// // Colour = colours.Blue,
// Shadow = false //
// }; // Shadow = false
// };
// case MatchType.TagTeamCoop: // case MatchType.TagTeamCoop:
// return new FillFlowContainer // return new FillFlowContainer
// { // {
// Anchor = Anchor.Centre, // Anchor = Anchor.Centre,
// Origin = Anchor.Centre, // Origin = Anchor.Centre,
// AutoSizeAxes = Axes.Both, // AutoSizeAxes = Axes.Both,
// Direction = FillDirection.Horizontal, // Direction = FillDirection.Horizontal,
// Spacing = new Vector2(2f), // Spacing = new Vector2(2f),
// Children = new[] // Children = new[]
// { // {
// new SpriteIcon // new SpriteIcon
// { // {
// Icon = FontAwesome.Solid.Sync, // Icon = FontAwesome.Solid.Sync,
// Size = new Vector2(size * 0.75f), // Size = new Vector2(size * 0.75f),
// Colour = colours.Blue, // Colour = colours.Blue,
// Shadow = false, // Shadow = false,
// }, // },
// new SpriteIcon // new SpriteIcon
// { // {
// Icon = FontAwesome.Solid.Sync, // Icon = FontAwesome.Solid.Sync,
// Size = new Vector2(size * 0.75f), // Size = new Vector2(size * 0.75f),
// Colour = colours.Pink, // Colour = colours.Pink,
// Shadow = false, // Shadow = false,
// }, // },
// }, // },
// }; // };
#pragma warning restore IDE0055
} }
} }

View File

@ -1,4 +1,4 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<LangVersion>8.0</LangVersion> <LangVersion>8.0</LangVersion>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

View File

@ -56,6 +56,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{10DF8F12-50FD-45D8-8A38-17BA764BF54D}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{10DF8F12-50FD-45D8-8A38-17BA764BF54D}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig .editorconfig = .editorconfig
.globalconfig = .globalconfig
Directory.Build.props = Directory.Build.props Directory.Build.props = Directory.Build.props
osu.Android.props = osu.Android.props osu.Android.props = osu.Android.props
osu.iOS.props = osu.iOS.props osu.iOS.props = osu.iOS.props