-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25561 from peppy/menu-skin-editor-button
Add second level menu for editors
- Loading branch information
Showing
8 changed files
with
96 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,16 @@ | ||
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
#nullable disable | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using JetBrains.Annotations; | ||
using osu.Framework; | ||
using osu.Framework.Allocation; | ||
using osu.Framework.Audio; | ||
using osu.Framework.Audio.Sample; | ||
using osu.Framework.Bindables; | ||
using osu.Framework.Extensions.IEnumerableExtensions; | ||
using osu.Framework.Extensions.LocalisationExtensions; | ||
using osu.Framework.Graphics; | ||
using osu.Framework.Graphics.Containers; | ||
using osu.Framework.Graphics.Sprites; | ||
|
@@ -36,29 +34,29 @@ namespace osu.Game.Screens.Menu | |
{ | ||
public partial class ButtonSystem : Container, IStateful<ButtonSystemState>, IKeyBindingHandler<GlobalAction> | ||
{ | ||
public event Action<ButtonSystemState> StateChanged; | ||
public const float BUTTON_WIDTH = 140f; | ||
public const float WEDGE_WIDTH = 20; | ||
|
||
private readonly IBindable<bool> isIdle = new BindableBool(); | ||
public event Action<ButtonSystemState>? StateChanged; | ||
|
||
public Action OnEdit; | ||
public Action OnExit; | ||
public Action OnBeatmapListing; | ||
public Action OnSolo; | ||
public Action OnSettings; | ||
public Action OnMultiplayer; | ||
public Action OnPlaylists; | ||
public Action? OnEditBeatmap; | ||
public Action? OnEditSkin; | ||
public Action? OnExit; | ||
public Action? OnBeatmapListing; | ||
public Action? OnSolo; | ||
public Action? OnSettings; | ||
public Action? OnMultiplayer; | ||
public Action? OnPlaylists; | ||
|
||
public const float BUTTON_WIDTH = 140f; | ||
public const float WEDGE_WIDTH = 20; | ||
private readonly IBindable<bool> isIdle = new BindableBool(); | ||
|
||
[CanBeNull] | ||
private OsuLogo logo; | ||
private OsuLogo? logo; | ||
|
||
/// <summary> | ||
/// Assign the <see cref="OsuLogo"/> that this ButtonSystem should manage the position of. | ||
/// </summary> | ||
/// <param name="logo">The instance of the logo to be assigned. If null, we are suspending from the screen that uses this ButtonSystem.</param> | ||
public void SetOsuLogo(OsuLogo logo) | ||
public void SetOsuLogo(OsuLogo? logo) | ||
{ | ||
this.logo = logo; | ||
|
||
|
@@ -84,9 +82,10 @@ public void SetOsuLogo(OsuLogo logo) | |
|
||
private readonly List<MainMenuButton> buttonsTopLevel = new List<MainMenuButton>(); | ||
private readonly List<MainMenuButton> buttonsPlay = new List<MainMenuButton>(); | ||
private readonly List<MainMenuButton> buttonsEdit = new List<MainMenuButton>(); | ||
|
||
private Sample sampleBackToLogo; | ||
private Sample sampleLogoSwoosh; | ||
private Sample? sampleBackToLogo; | ||
private Sample? sampleLogoSwoosh; | ||
|
||
private readonly LogoTrackingContainer logoTrackingContainer; | ||
|
||
|
@@ -108,39 +107,45 @@ public ButtonSystem() | |
backButton = new MainMenuButton(ButtonSystemStrings.Back, @"back-to-top", OsuIcon.LeftCircle, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, | ||
-WEDGE_WIDTH) | ||
{ | ||
VisibleState = ButtonSystemState.Play, | ||
VisibleStateMin = ButtonSystemState.Play, | ||
VisibleStateMax = ButtonSystemState.Edit, | ||
}, | ||
logoTrackingContainer.LogoFacade.With(d => d.Scale = new Vector2(0.74f)) | ||
}); | ||
|
||
buttonArea.Flow.CentreTarget = logoTrackingContainer.LogoFacade; | ||
} | ||
|
||
[Resolved(CanBeNull = true)] | ||
private OsuGame game { get; set; } | ||
[Resolved] | ||
private IAPIProvider api { get; set; } = null!; | ||
|
||
[Resolved] | ||
private IAPIProvider api { get; set; } | ||
private OsuGame? game { get; set; } | ||
|
||
[Resolved(CanBeNull = true)] | ||
private LoginOverlay loginOverlay { get; set; } | ||
[Resolved] | ||
private LoginOverlay? loginOverlay { get; set; } | ||
|
||
[BackgroundDependencyLoader(true)] | ||
private void load(AudioManager audio, IdleTracker idleTracker, GameHost host) | ||
[BackgroundDependencyLoader] | ||
private void load(AudioManager audio, IdleTracker? idleTracker, GameHost host) | ||
{ | ||
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Solo, @"button-default-select", FontAwesome.Solid.User, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P)); | ||
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Multi, @"button-default-select", FontAwesome.Solid.Users, new Color4(94, 63, 186, 255), onMultiplayer, 0, Key.M)); | ||
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Playlists, @"button-default-select", OsuIcon.Charts, new Color4(94, 63, 186, 255), onPlaylists, 0, Key.L)); | ||
buttonsPlay.ForEach(b => b.VisibleState = ButtonSystemState.Play); | ||
|
||
buttonsEdit.Add(new MainMenuButton(EditorStrings.BeatmapEditor.ToLower(), @"button-default-select", HexaconsIcons.Beatmap, new Color4(238, 170, 0, 255), () => OnEditBeatmap?.Invoke(), WEDGE_WIDTH, Key.B)); | ||
buttonsEdit.Add(new MainMenuButton(SkinEditorStrings.SkinEditor.ToLower(), @"button-default-select", HexaconsIcons.Editor, new Color4(220, 160, 0, 255), () => OnEditSkin?.Invoke(), 0, Key.S)); | ||
buttonsEdit.ForEach(b => b.VisibleState = ButtonSystemState.Edit); | ||
|
||
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Play, @"button-play-select", OsuIcon.Logo, new Color4(102, 68, 204, 255), () => State = ButtonSystemState.Play, WEDGE_WIDTH, Key.P)); | ||
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Edit, @"button-default-select", OsuIcon.EditCircle, new Color4(238, 170, 0, 255), () => OnEdit?.Invoke(), 0, Key.E)); | ||
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Edit, @"button-default-select", OsuIcon.EditCircle, new Color4(238, 170, 0, 255), () => State = ButtonSystemState.Edit, 0, Key.E)); | ||
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Browse, @"button-default-select", OsuIcon.ChevronDownCircle, new Color4(165, 204, 0, 255), () => OnBeatmapListing?.Invoke(), 0, Key.B, Key.D)); | ||
|
||
if (host.CanExit) | ||
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Exit, string.Empty, OsuIcon.CrossCircle, new Color4(238, 51, 153, 255), () => OnExit?.Invoke(), 0, Key.Q)); | ||
|
||
buttonArea.AddRange(buttonsPlay); | ||
buttonArea.AddRange(buttonsEdit); | ||
buttonArea.AddRange(buttonsTopLevel); | ||
|
||
buttonArea.ForEach(b => | ||
|
@@ -270,6 +275,7 @@ private bool goBack() | |
|
||
return true; | ||
|
||
case ButtonSystemState.Edit: | ||
case ButtonSystemState.Play: | ||
StopSamplePlayback(); | ||
backButton.TriggerClick(); | ||
|
@@ -328,6 +334,8 @@ public ButtonSystemState State | |
|
||
Logger.Log($"{nameof(ButtonSystem)}'s state changed from {lastState} to {state}"); | ||
|
||
buttonArea.FinishTransforms(true); | ||
|
||
using (buttonArea.BeginDelayedSequence(lastState == ButtonSystemState.Initial ? 150 : 0)) | ||
{ | ||
buttonArea.ButtonSystemState = state; | ||
|
@@ -340,7 +348,7 @@ public ButtonSystemState State | |
} | ||
} | ||
|
||
private ScheduledDelegate logoDelayedAction; | ||
private ScheduledDelegate? logoDelayedAction; | ||
|
||
private void updateLogoState(ButtonSystemState lastState = ButtonSystemState.Initial) | ||
{ | ||
|
@@ -414,6 +422,7 @@ public enum ButtonSystemState | |
Initial, | ||
TopLevel, | ||
Play, | ||
Edit, | ||
EnteringMode, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,6 @@ | ||
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
#nullable disable | ||
|
||
using System; | ||
using System.Linq; | ||
using osu.Framework; | ||
|
@@ -33,7 +31,7 @@ namespace osu.Game.Screens.Menu | |
/// </summary> | ||
public partial class MainMenuButton : BeatSyncedContainer, IStateful<ButtonState> | ||
{ | ||
public event Action<ButtonState> StateChanged; | ||
public event Action<ButtonState>? StateChanged; | ||
|
||
public readonly Key[] TriggerKeys; | ||
|
||
|
@@ -44,18 +42,28 @@ public partial class MainMenuButton : BeatSyncedContainer, IStateful<ButtonState | |
private readonly string sampleName; | ||
|
||
/// <summary> | ||
/// The menu state for which we are visible for. | ||
/// The menu state for which we are visible for (assuming only one). | ||
/// </summary> | ||
public ButtonSystemState VisibleState = ButtonSystemState.TopLevel; | ||
public ButtonSystemState VisibleState | ||
{ | ||
set | ||
{ | ||
VisibleStateMin = value; | ||
VisibleStateMax = value; | ||
} | ||
} | ||
|
||
public ButtonSystemState VisibleStateMin = ButtonSystemState.TopLevel; | ||
public ButtonSystemState VisibleStateMax = ButtonSystemState.TopLevel; | ||
|
||
private readonly Action clickAction; | ||
private Sample sampleClick; | ||
private Sample sampleHover; | ||
private SampleChannel sampleChannel; | ||
private readonly Action? clickAction; | ||
private Sample? sampleClick; | ||
private Sample? sampleHover; | ||
private SampleChannel? sampleChannel; | ||
|
||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => box.ReceivePositionalInputAt(screenSpacePos); | ||
|
||
public MainMenuButton(LocalisableString text, string sampleName, IconUsage symbol, Color4 colour, Action clickAction = null, float extraWidth = 0, params Key[] triggerKeys) | ||
public MainMenuButton(LocalisableString text, string sampleName, IconUsage symbol, Color4 colour, Action? clickAction = null, float extraWidth = 0, params Key[] triggerKeys) | ||
{ | ||
this.sampleName = sampleName; | ||
this.clickAction = clickAction; | ||
|
@@ -315,9 +323,9 @@ public ButtonSystemState ButtonSystemState | |
break; | ||
|
||
default: | ||
if (value == VisibleState) | ||
if (value <= VisibleStateMax && value >= VisibleStateMin) | ||
State = ButtonState.Expanded; | ||
else if (value < VisibleState) | ||
else if (value < VisibleStateMin) | ||
State = ButtonState.Contracted; | ||
else | ||
State = ButtonState.Exploded; | ||
|