mirror of
https://github.com/ppy/osu.git
synced 2025-01-26 18:52:55 +08:00
Merge branch 'master' into skin-fuck
This commit is contained in:
commit
6542f974f2
@ -27,7 +27,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ppy.localisationanalyser.tools": {
|
"ppy.localisationanalyser.tools": {
|
||||||
"version": "2021.1210.0",
|
"version": "2022.320.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"localisation"
|
"localisation"
|
||||||
]
|
]
|
||||||
|
5
.vscode/extensions.json
vendored
Normal file
5
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"ms-dotnettools.csharp"
|
||||||
|
]
|
||||||
|
}
|
@ -13,6 +13,7 @@ using osu.Framework.Testing;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Overlays.Dialog;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Catch;
|
using osu.Game.Rulesets.Catch;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
@ -23,6 +24,7 @@ using osu.Game.Screens.Edit.Setup;
|
|||||||
using osu.Game.Storyboards;
|
using osu.Game.Storyboards;
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
using osuTK.Input;
|
||||||
using SharpCompress.Archives;
|
using SharpCompress.Archives;
|
||||||
using SharpCompress.Archives.Zip;
|
using SharpCompress.Archives.Zip;
|
||||||
|
|
||||||
@ -63,13 +65,19 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
EditorBeatmap editorBeatmap = null;
|
EditorBeatmap editorBeatmap = null;
|
||||||
|
|
||||||
AddStep("store editor beatmap", () => editorBeatmap = EditorBeatmap);
|
AddStep("store editor beatmap", () => editorBeatmap = EditorBeatmap);
|
||||||
AddStep("exit without save", () =>
|
|
||||||
|
AddStep("exit without save", () => Editor.Exit());
|
||||||
|
AddStep("hold to confirm", () =>
|
||||||
{
|
{
|
||||||
Editor.Exit();
|
var confirmButton = DialogOverlay.CurrentDialog.ChildrenOfType<PopupDialogDangerousButton>().First();
|
||||||
DialogOverlay.CurrentDialog.PerformOkAction();
|
|
||||||
|
InputManager.MoveMouseTo(confirmButton);
|
||||||
|
InputManager.PressButton(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for exit", () => !Editor.IsCurrentScreen());
|
AddUntilStep("wait for exit", () => !Editor.IsCurrentScreen());
|
||||||
|
AddStep("release", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
|
|
||||||
AddAssert("new beatmap not persisted", () => beatmapManager.QueryBeatmapSet(s => s.ID == editorBeatmap.BeatmapInfo.BeatmapSet.ID)?.Value.DeletePending == true);
|
AddAssert("new beatmap not persisted", () => beatmapManager.QueryBeatmapSet(s => s.ID == editorBeatmap.BeatmapInfo.BeatmapSet.ID)?.Value.DeletePending == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,13 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
{
|
{
|
||||||
public class TestSceneEditorSaving : EditorSavingTestScene
|
public class TestSceneEditorSaving : EditorSavingTestScene
|
||||||
{
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestCantExitWithoutSaving()
|
||||||
|
{
|
||||||
|
AddRepeatStep("Exit", () => InputManager.Key(Key.Escape), 10);
|
||||||
|
AddAssert("Editor is still active screen", () => Game.ScreenStack.CurrentScreen is Editor);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestMetadata()
|
public void TestMetadata()
|
||||||
{
|
{
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
// 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 System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
||||||
using osu.Game.Skinning.Editor;
|
using osu.Game.Skinning.Editor;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
@ -29,7 +34,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddStep("reload skin editor", () =>
|
AddStep("reload skin editor", () =>
|
||||||
{
|
{
|
||||||
skinEditor?.Expire();
|
skinEditor?.Expire();
|
||||||
Player.ScaleTo(0.8f);
|
Player.ScaleTo(0.4f);
|
||||||
LoadComponentAsync(skinEditor = new SkinEditor(Player), Add);
|
LoadComponentAsync(skinEditor = new SkinEditor(Player), Add);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -40,6 +45,36 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddToggleStep("toggle editor visibility", visible => skinEditor.ToggleVisibility());
|
AddToggleStep("toggle editor visibility", visible => skinEditor.ToggleVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestEditComponent()
|
||||||
|
{
|
||||||
|
BarHitErrorMeter hitErrorMeter = null;
|
||||||
|
|
||||||
|
AddStep("select bar hit error blueprint", () =>
|
||||||
|
{
|
||||||
|
var blueprint = skinEditor.ChildrenOfType<SkinBlueprint>().First(b => b.Item is BarHitErrorMeter);
|
||||||
|
|
||||||
|
hitErrorMeter = (BarHitErrorMeter)blueprint.Item;
|
||||||
|
skinEditor.SelectedComponents.Clear();
|
||||||
|
skinEditor.SelectedComponents.Add(blueprint.Item);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("value is default", () => hitErrorMeter.JudgementLineThickness.IsDefault);
|
||||||
|
|
||||||
|
AddStep("hover first slider", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(
|
||||||
|
skinEditor.ChildrenOfType<SkinSettingsToolbox>().First()
|
||||||
|
.ChildrenOfType<SettingsSlider<float>>().First()
|
||||||
|
.ChildrenOfType<SliderBar<float>>().First()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("adjust slider via keyboard", () => InputManager.Key(Key.Left));
|
||||||
|
|
||||||
|
AddAssert("value is less than default", () => hitErrorMeter.JudgementLineThickness.Value < hitErrorMeter.JudgementLineThickness.Default);
|
||||||
|
}
|
||||||
|
|
||||||
protected override Ruleset CreatePlayerRuleset() => new OsuRuleset();
|
protected override Ruleset CreatePlayerRuleset() => new OsuRuleset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -14,6 +15,7 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using osu.Game.Online.Leaderboards;
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Mods;
|
using osu.Game.Overlays.Mods;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Overlays.Toolbar;
|
using osu.Game.Overlays.Toolbar;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
@ -21,10 +23,12 @@ using osu.Game.Scoring;
|
|||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using osu.Game.Screens.OnlinePlay.Lounge;
|
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
using osu.Game.Screens.Select.Options;
|
using osu.Game.Screens.Select.Options;
|
||||||
|
using osu.Game.Skinning.Editor;
|
||||||
using osu.Game.Tests.Beatmaps.IO;
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
@ -66,6 +70,73 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
|
AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestEditComponentDuringGameplay()
|
||||||
|
{
|
||||||
|
Screens.Select.SongSelect songSelect = null;
|
||||||
|
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
|
||||||
|
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
|
||||||
|
|
||||||
|
AddStep("import beatmap", () => BeatmapImportHelper.LoadQuickOszIntoOsu(Game).WaitSafely());
|
||||||
|
|
||||||
|
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
|
||||||
|
|
||||||
|
SkinEditor skinEditor = null;
|
||||||
|
|
||||||
|
AddStep("open skin editor", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.ControlLeft);
|
||||||
|
InputManager.PressKey(Key.ShiftLeft);
|
||||||
|
InputManager.Key(Key.S);
|
||||||
|
InputManager.ReleaseKey(Key.ControlLeft);
|
||||||
|
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("get skin editor", () => (skinEditor = Game.ChildrenOfType<SkinEditor>().FirstOrDefault()) != null);
|
||||||
|
|
||||||
|
AddStep("Click gameplay scene button", () =>
|
||||||
|
{
|
||||||
|
skinEditor.ChildrenOfType<SkinEditorSceneLibrary.SceneButton>().First(b => b.Text == "Gameplay").TriggerClick();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for player", () =>
|
||||||
|
{
|
||||||
|
// dismiss any notifications that may appear (ie. muted notification).
|
||||||
|
clickMouseInCentre();
|
||||||
|
return Game.ScreenStack.CurrentScreen is Player;
|
||||||
|
});
|
||||||
|
|
||||||
|
BarHitErrorMeter hitErrorMeter = null;
|
||||||
|
|
||||||
|
AddUntilStep("select bar hit error blueprint", () =>
|
||||||
|
{
|
||||||
|
var blueprint = skinEditor.ChildrenOfType<SkinBlueprint>().FirstOrDefault(b => b.Item is BarHitErrorMeter);
|
||||||
|
|
||||||
|
if (blueprint == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
hitErrorMeter = (BarHitErrorMeter)blueprint.Item;
|
||||||
|
skinEditor.SelectedComponents.Clear();
|
||||||
|
skinEditor.SelectedComponents.Add(blueprint.Item);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("value is default", () => hitErrorMeter.JudgementLineThickness.IsDefault);
|
||||||
|
|
||||||
|
AddStep("hover first slider", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(
|
||||||
|
skinEditor.ChildrenOfType<SkinSettingsToolbox>().First()
|
||||||
|
.ChildrenOfType<SettingsSlider<float>>().First()
|
||||||
|
.ChildrenOfType<SliderBar<float>>().First()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("adjust slider via keyboard", () => InputManager.Key(Key.Left));
|
||||||
|
|
||||||
|
AddAssert("value is less than default", () => hitErrorMeter.JudgementLineThickness.Value < hitErrorMeter.JudgementLineThickness.Default);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestRetryCountIncrements()
|
public void TestRetryCountIncrements()
|
||||||
{
|
{
|
||||||
@ -120,7 +191,8 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
|
|
||||||
AddStep("press back button", () => Game.ChildrenOfType<BackButton>().First().Action());
|
AddStep("press back button", () => Game.ChildrenOfType<BackButton>().First().Action());
|
||||||
|
|
||||||
AddStep("show local scores", () => Game.ChildrenOfType<BeatmapDetailAreaTabControl>().First().Current.Value = new BeatmapDetailAreaLeaderboardTabItem<BeatmapLeaderboardScope>(BeatmapLeaderboardScope.Local));
|
AddStep("show local scores",
|
||||||
|
() => Game.ChildrenOfType<BeatmapDetailAreaTabControl>().First().Current.Value = new BeatmapDetailAreaLeaderboardTabItem<BeatmapLeaderboardScope>(BeatmapLeaderboardScope.Local));
|
||||||
|
|
||||||
AddUntilStep("wait for score displayed", () => (scorePanel = Game.ChildrenOfType<LeaderboardScore>().FirstOrDefault(s => s.Score.Equals(score))) != null);
|
AddUntilStep("wait for score displayed", () => (scorePanel = Game.ChildrenOfType<LeaderboardScore>().FirstOrDefault(s => s.Score.Equals(score))) != null);
|
||||||
|
|
||||||
@ -152,7 +224,8 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
|
|
||||||
AddStep("press back button", () => Game.ChildrenOfType<BackButton>().First().Action());
|
AddStep("press back button", () => Game.ChildrenOfType<BackButton>().First().Action());
|
||||||
|
|
||||||
AddStep("show local scores", () => Game.ChildrenOfType<BeatmapDetailAreaTabControl>().First().Current.Value = new BeatmapDetailAreaLeaderboardTabItem<BeatmapLeaderboardScope>(BeatmapLeaderboardScope.Local));
|
AddStep("show local scores",
|
||||||
|
() => Game.ChildrenOfType<BeatmapDetailAreaTabControl>().First().Current.Value = new BeatmapDetailAreaLeaderboardTabItem<BeatmapLeaderboardScope>(BeatmapLeaderboardScope.Local));
|
||||||
|
|
||||||
AddUntilStep("wait for score displayed", () => (scorePanel = Game.ChildrenOfType<LeaderboardScore>().FirstOrDefault(s => s.Score.Equals(score))) != null);
|
AddUntilStep("wait for score displayed", () => (scorePanel = Game.ChildrenOfType<LeaderboardScore>().FirstOrDefault(s => s.Score.Equals(score))) != null);
|
||||||
|
|
||||||
@ -262,6 +335,20 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
exitViaBackButtonAndConfirm();
|
exitViaBackButtonAndConfirm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestModsResetOnEnteringMultiplayer()
|
||||||
|
{
|
||||||
|
var osuAutomationMod = new OsuModAutoplay();
|
||||||
|
|
||||||
|
AddStep("Enable autoplay", () => { Game.SelectedMods.Value = new[] { osuAutomationMod }; });
|
||||||
|
|
||||||
|
PushAndConfirm(() => new Screens.OnlinePlay.Multiplayer.Multiplayer());
|
||||||
|
AddUntilStep("Mods are removed", () => Game.SelectedMods.Value.Count == 0);
|
||||||
|
|
||||||
|
AddStep("Return to menu", () => Game.ScreenStack.CurrentScreen.Exit());
|
||||||
|
AddUntilStep("Mods are restored", () => Game.SelectedMods.Value.Contains(osuAutomationMod));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestExitMultiWithEscape()
|
public void TestExitMultiWithEscape()
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,10 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
Text = @"You're a fake!",
|
Text = @"You're a fake!",
|
||||||
},
|
},
|
||||||
|
new PopupDialogDangerousButton
|
||||||
|
{
|
||||||
|
Text = @"Careful with this one..",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,14 @@ namespace osu.Game.Graphics.Containers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual bool AllowMultipleFires => false;
|
protected virtual bool AllowMultipleFires => false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specify a custom activation delay, overriding the game-wide user setting.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This should be used in special cases where we want to be extra sure the user knows what they are doing. An example is when changes would be lost.
|
||||||
|
/// </remarks>
|
||||||
|
protected virtual double? HoldActivationDelay => null;
|
||||||
|
|
||||||
public Bindable<double> Progress = new BindableDouble();
|
public Bindable<double> Progress = new BindableDouble();
|
||||||
|
|
||||||
private Bindable<double> holdActivationDelay;
|
private Bindable<double> holdActivationDelay;
|
||||||
@ -35,7 +43,9 @@ namespace osu.Game.Graphics.Containers
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
holdActivationDelay = config.GetBindable<double>(OsuSetting.UIHoldActivationDelay);
|
holdActivationDelay = HoldActivationDelay != null
|
||||||
|
? new Bindable<double>(HoldActivationDelay.Value)
|
||||||
|
: config.GetBindable<double>(OsuSetting.UIHoldActivationDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void BeginConfirm()
|
protected void BeginConfirm()
|
||||||
|
@ -45,8 +45,9 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected readonly Container ColourContainer;
|
||||||
|
|
||||||
private readonly Container backgroundContainer;
|
private readonly Container backgroundContainer;
|
||||||
private readonly Container colourContainer;
|
|
||||||
private readonly Container glowContainer;
|
private readonly Container glowContainer;
|
||||||
private readonly Box leftGlow;
|
private readonly Box leftGlow;
|
||||||
private readonly Box centerGlow;
|
private readonly Box centerGlow;
|
||||||
@ -113,7 +114,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Masking = true,
|
Masking = true,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
colourContainer = new Container
|
ColourContainer = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -182,7 +183,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
buttonColour = value;
|
buttonColour = value;
|
||||||
updateGlow();
|
updateGlow();
|
||||||
colourContainer.Colour = value;
|
ColourContainer.Colour = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,11 +231,11 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Alpha = 0.05f
|
Alpha = 0.05f
|
||||||
};
|
};
|
||||||
|
|
||||||
colourContainer.Add(flash);
|
ColourContainer.Add(flash);
|
||||||
flash.FadeOutFromOne(100).Expire();
|
flash.FadeOutFromOne(100).Expire();
|
||||||
|
|
||||||
clickAnimating = true;
|
clickAnimating = true;
|
||||||
colourContainer.ResizeWidthTo(colourContainer.Width * 1.05f, 100, Easing.OutQuint)
|
ColourContainer.ResizeWidthTo(ColourContainer.Width * 1.05f, 100, Easing.OutQuint)
|
||||||
.OnComplete(_ =>
|
.OnComplete(_ =>
|
||||||
{
|
{
|
||||||
clickAnimating = false;
|
clickAnimating = false;
|
||||||
@ -246,14 +247,14 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected override bool OnMouseDown(MouseDownEvent e)
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
{
|
{
|
||||||
colourContainer.ResizeWidthTo(hover_width * 0.98f, click_duration * 4, Easing.OutQuad);
|
ColourContainer.ResizeWidthTo(hover_width * 0.98f, click_duration * 4, Easing.OutQuad);
|
||||||
return base.OnMouseDown(e);
|
return base.OnMouseDown(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnMouseUp(MouseUpEvent e)
|
protected override void OnMouseUp(MouseUpEvent e)
|
||||||
{
|
{
|
||||||
if (State == SelectionState.Selected)
|
if (State == SelectionState.Selected)
|
||||||
colourContainer.ResizeWidthTo(hover_width, click_duration, Easing.In);
|
ColourContainer.ResizeWidthTo(hover_width, click_duration, Easing.In);
|
||||||
base.OnMouseUp(e);
|
base.OnMouseUp(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,12 +280,12 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
if (newState == SelectionState.Selected)
|
if (newState == SelectionState.Selected)
|
||||||
{
|
{
|
||||||
spriteText.TransformSpacingTo(hoverSpacing, hover_duration, Easing.OutElastic);
|
spriteText.TransformSpacingTo(hoverSpacing, hover_duration, Easing.OutElastic);
|
||||||
colourContainer.ResizeWidthTo(hover_width, hover_duration, Easing.OutElastic);
|
ColourContainer.ResizeWidthTo(hover_width, hover_duration, Easing.OutElastic);
|
||||||
glowContainer.FadeIn(hover_duration, Easing.OutQuint);
|
glowContainer.FadeIn(hover_duration, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
colourContainer.ResizeWidthTo(idle_width, hover_duration, Easing.OutElastic);
|
ColourContainer.ResizeWidthTo(idle_width, hover_duration, Easing.OutElastic);
|
||||||
spriteText.TransformSpacingTo(Vector2.Zero, hover_duration, Easing.OutElastic);
|
spriteText.TransformSpacingTo(Vector2.Zero, hover_duration, Easing.OutElastic);
|
||||||
glowContainer.FadeOut(hover_duration, Easing.OutQuint);
|
glowContainer.FadeOut(hover_duration, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
@ -1046,6 +1046,10 @@ namespace osu.Game
|
|||||||
|
|
||||||
switch (e.Action)
|
switch (e.Action)
|
||||||
{
|
{
|
||||||
|
case GlobalAction.ToggleSkinEditor:
|
||||||
|
skinEditor.ToggleVisibility();
|
||||||
|
return true;
|
||||||
|
|
||||||
case GlobalAction.ResetInputSettings:
|
case GlobalAction.ResetInputSettings:
|
||||||
Host.ResetInputHandlers();
|
Host.ResetInputHandlers();
|
||||||
frameworkConfig.GetBindable<ConfineMouseMode>(FrameworkSetting.ConfineMouseMode).SetDefault();
|
frameworkConfig.GetBindable<ConfineMouseMode>(FrameworkSetting.ConfineMouseMode).SetDefault();
|
||||||
|
@ -219,7 +219,12 @@ namespace osu.Game.Overlays.Dialog
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Programmatically clicks the first <see cref="PopupDialogOkButton"/>.
|
/// Programmatically clicks the first <see cref="PopupDialogOkButton"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PerformOkAction() => Buttons.OfType<PopupDialogOkButton>().First().TriggerClick();
|
public void PerformOkAction() => PerformAction<PopupDialogOkButton>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Programmatically clicks the first button of the provided type.
|
||||||
|
/// </summary>
|
||||||
|
public void PerformAction<T>() where T : PopupDialogButton => Buttons.OfType<T>().First().TriggerClick();
|
||||||
|
|
||||||
protected override bool OnKeyDown(KeyDownEvent e)
|
protected override bool OnKeyDown(KeyDownEvent e)
|
||||||
{
|
{
|
||||||
|
59
osu.Game/Overlays/Dialog/PopupDialogDangerousButton.cs
Normal file
59
osu.Game/Overlays/Dialog/PopupDialogDangerousButton.cs
Normal file
@ -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 osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Dialog
|
||||||
|
{
|
||||||
|
public class PopupDialogDangerousButton : PopupDialogButton
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
ButtonColour = colours.Red3;
|
||||||
|
|
||||||
|
ColourContainer.Add(new ConfirmFillBox
|
||||||
|
{
|
||||||
|
Action = () => Action(),
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Blending = BlendingParameters.Additive,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ConfirmFillBox : HoldToConfirmContainer
|
||||||
|
{
|
||||||
|
private Box box;
|
||||||
|
|
||||||
|
protected override double? HoldActivationDelay => 500;
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Child = box = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
};
|
||||||
|
|
||||||
|
Progress.BindValueChanged(progress => box.Width = (float)progress.NewValue, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
|
{
|
||||||
|
BeginConfirm();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseUp(MouseUpEvent e)
|
||||||
|
{
|
||||||
|
if (!e.HasAnyButtonPressed)
|
||||||
|
AbortConfirm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Settings.Sections
|
|||||||
new SettingsButton
|
new SettingsButton
|
||||||
{
|
{
|
||||||
Text = SkinSettingsStrings.SkinLayoutEditor,
|
Text = SkinSettingsStrings.SkinLayoutEditor,
|
||||||
Action = () => skinEditor?.Toggle(),
|
Action = () => skinEditor?.ToggleVisibility(),
|
||||||
},
|
},
|
||||||
new ExportSkinButton(),
|
new ExportSkinButton(),
|
||||||
};
|
};
|
||||||
|
@ -97,7 +97,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
private bool canSave;
|
private bool canSave;
|
||||||
|
|
||||||
private bool exitConfirmed;
|
protected bool ExitConfirmed { get; private set; }
|
||||||
|
|
||||||
private string lastSavedHash;
|
private string lastSavedHash;
|
||||||
|
|
||||||
@ -586,7 +586,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
public override bool OnExiting(IScreen next)
|
public override bool OnExiting(IScreen next)
|
||||||
{
|
{
|
||||||
if (!exitConfirmed)
|
if (!ExitConfirmed)
|
||||||
{
|
{
|
||||||
// dialog overlay may not be available in visual tests.
|
// dialog overlay may not be available in visual tests.
|
||||||
if (dialogOverlay == null)
|
if (dialogOverlay == null)
|
||||||
@ -595,12 +595,9 @@ namespace osu.Game.Screens.Edit
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the dialog is already displayed, confirm exit with no save.
|
// if the dialog is already displayed, block exiting until the user explicitly makes a decision.
|
||||||
if (dialogOverlay.CurrentDialog is PromptForSaveDialog saveDialog)
|
if (dialogOverlay.CurrentDialog is PromptForSaveDialog)
|
||||||
{
|
|
||||||
saveDialog.PerformOkAction();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
if (isNewBeatmap || HasUnsavedChanges)
|
if (isNewBeatmap || HasUnsavedChanges)
|
||||||
{
|
{
|
||||||
@ -645,7 +642,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
{
|
{
|
||||||
Save();
|
Save();
|
||||||
|
|
||||||
exitConfirmed = true;
|
ExitConfirmed = true;
|
||||||
this.Exit();
|
this.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,7 +665,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
Beatmap.SetDefault();
|
Beatmap.SetDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
exitConfirmed = true;
|
ExitConfirmed = true;
|
||||||
this.Exit();
|
this.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,12 +17,12 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
Buttons = new PopupDialogButton[]
|
Buttons = new PopupDialogButton[]
|
||||||
{
|
{
|
||||||
new PopupDialogCancelButton
|
new PopupDialogOkButton
|
||||||
{
|
{
|
||||||
Text = @"Save my masterpiece!",
|
Text = @"Save my masterpiece!",
|
||||||
Action = saveAndExit
|
Action = saveAndExit
|
||||||
},
|
},
|
||||||
new PopupDialogOkButton
|
new PopupDialogDangerousButton
|
||||||
{
|
{
|
||||||
Text = @"Forget all changes",
|
Text = @"Forget all changes",
|
||||||
Action = exit
|
Action = exit
|
||||||
|
@ -115,6 +115,8 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
this.FadeIn();
|
this.FadeIn();
|
||||||
waves.Show();
|
waves.Show();
|
||||||
|
|
||||||
|
Mods.SetDefault();
|
||||||
|
|
||||||
if (loungeSubScreen.IsCurrentScreen())
|
if (loungeSubScreen.IsCurrentScreen())
|
||||||
loungeSubScreen.OnEntering(last);
|
loungeSubScreen.OnEntering(last);
|
||||||
else
|
else
|
||||||
|
@ -19,15 +19,15 @@ namespace osu.Game.Skinning.Editor
|
|||||||
/// A container which handles loading a skin editor on user request for a specified target.
|
/// A container which handles loading a skin editor on user request for a specified target.
|
||||||
/// This also handles the scaling / positioning adjustment of the target.
|
/// This also handles the scaling / positioning adjustment of the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SkinEditorOverlay : CompositeDrawable, IKeyBindingHandler<GlobalAction>
|
public class SkinEditorOverlay : OverlayContainer, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
private readonly ScalingContainer scalingContainer;
|
private readonly ScalingContainer scalingContainer;
|
||||||
|
|
||||||
|
protected override bool BlockNonPositionalInput => true;
|
||||||
|
|
||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private SkinEditor skinEditor;
|
private SkinEditor skinEditor;
|
||||||
|
|
||||||
public const float VISIBLE_TARGET_SCALE = 0.8f;
|
|
||||||
|
|
||||||
[Resolved(canBeNull: true)]
|
[Resolved(canBeNull: true)]
|
||||||
private OsuGame game { get; set; }
|
private OsuGame game { get; set; }
|
||||||
|
|
||||||
@ -49,33 +49,13 @@ namespace osu.Game.Skinning.Editor
|
|||||||
|
|
||||||
Hide();
|
Hide();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case GlobalAction.ToggleSkinEditor:
|
|
||||||
Toggle();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Toggle()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
if (skinEditor == null)
|
|
||||||
Show();
|
|
||||||
else
|
|
||||||
skinEditor.ToggleVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Hide()
|
|
||||||
{
|
|
||||||
// base call intentionally omitted.
|
|
||||||
skinEditor?.Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Show()
|
|
||||||
{
|
|
||||||
// base call intentionally omitted as we have custom behaviour.
|
|
||||||
|
|
||||||
if (skinEditor != null)
|
if (skinEditor != null)
|
||||||
{
|
{
|
||||||
skinEditor.Show();
|
skinEditor.Show();
|
||||||
@ -83,29 +63,24 @@ namespace osu.Game.Skinning.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
var editor = new SkinEditor();
|
var editor = new SkinEditor();
|
||||||
|
|
||||||
editor.State.BindValueChanged(visibility => updateComponentVisibility());
|
editor.State.BindValueChanged(visibility => updateComponentVisibility());
|
||||||
|
|
||||||
skinEditor = editor;
|
skinEditor = editor;
|
||||||
|
|
||||||
// Schedule ensures that if `Show` is called before this overlay is loaded,
|
LoadComponentAsync(editor, _ =>
|
||||||
// it will not throw (LoadComponentAsync requires the load target to be in a loaded state).
|
|
||||||
Schedule(() =>
|
|
||||||
{
|
{
|
||||||
if (editor != skinEditor)
|
if (editor != skinEditor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LoadComponentAsync(editor, _ =>
|
AddInternal(editor);
|
||||||
{
|
|
||||||
if (editor != skinEditor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AddInternal(editor);
|
SetTarget(lastTargetScreen);
|
||||||
|
|
||||||
SetTarget(lastTargetScreen);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void PopOut() => skinEditor?.Hide();
|
||||||
|
|
||||||
private void updateComponentVisibility()
|
private void updateComponentVisibility()
|
||||||
{
|
{
|
||||||
Debug.Assert(skinEditor != null);
|
Debug.Assert(skinEditor != null);
|
||||||
|
@ -104,7 +104,7 @@ namespace osu.Game.Skinning.Editor
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SceneButton : OsuButton
|
public class SceneButton : OsuButton
|
||||||
{
|
{
|
||||||
public SceneButton()
|
public SceneButton()
|
||||||
{
|
{
|
||||||
|
@ -7,10 +7,13 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.Dialog;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
@ -93,6 +96,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
protected class TestEditor : Editor
|
protected class TestEditor : Editor
|
||||||
{
|
{
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
[CanBeNull]
|
||||||
|
private DialogOverlay dialogOverlay { get; set; }
|
||||||
|
|
||||||
public new void Undo() => base.Undo();
|
public new void Undo() => base.Undo();
|
||||||
|
|
||||||
public new void Redo() => base.Redo();
|
public new void Redo() => base.Redo();
|
||||||
@ -111,6 +118,18 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
public new bool HasUnsavedChanges => base.HasUnsavedChanges;
|
public new bool HasUnsavedChanges => base.HasUnsavedChanges;
|
||||||
|
|
||||||
|
public override bool OnExiting(IScreen next)
|
||||||
|
{
|
||||||
|
// For testing purposes allow the screen to exit without saving on second attempt.
|
||||||
|
if (!ExitConfirmed && dialogOverlay?.CurrentDialog is PromptForSaveDialog saveDialog)
|
||||||
|
{
|
||||||
|
saveDialog.PerformAction<PopupDialogDangerousButton>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnExiting(next);
|
||||||
|
}
|
||||||
|
|
||||||
public TestEditor(EditorLoader loader = null)
|
public TestEditor(EditorLoader loader = null)
|
||||||
: base(loader)
|
: base(loader)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
|
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="ppy.LocalisationAnalyser" Version="2021.1210.0">
|
<PackageReference Include="ppy.LocalisationAnalyser" Version="2022.320.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
Loading…
Reference in New Issue
Block a user