1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-14 05:47:20 +08:00

Merge pull request #31784 from bdach/bss/wizard-appearance

Implement visual appearance of beatmap submission wizard
This commit is contained in:
Dean Herbert 2025-02-05 17:34:30 +09:00 committed by GitHub
commit 9b79cf6c61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 389 additions and 8 deletions

View File

@ -0,0 +1,41 @@
// 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.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Screens.Edit.Submission;
using osu.Game.Screens.Footer;
namespace osu.Game.Tests.Visual.Editing
{
public partial class TestSceneBeatmapSubmissionOverlay : OsuTestScene
{
private ScreenFooter footer = null!;
[SetUpSteps]
public void SetUpSteps()
{
AddStep("add overlay", () =>
{
var receptor = new ScreenFooter.BackReceptor();
footer = new ScreenFooter(receptor);
Child = new DependencyProvidingContainer
{
RelativeSizeAxes = Axes.Both,
CachedDependencies = new[] { (typeof(ScreenFooter), (object)footer) },
Children = new Drawable[]
{
receptor,
new BeatmapSubmissionOverlay
{
State = { Value = Visibility.Visible, },
},
footer,
}
};
});
}
}
}

View File

@ -220,6 +220,9 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.AlwaysShowHoldForMenuButton, false);
SetDefault(OsuSetting.AlwaysRequireHoldingForPause, false);
SetDefault(OsuSetting.EditorShowStoryboard, true);
SetDefault(OsuSetting.EditorSubmissionNotifyOnDiscussionReplies, true);
SetDefault(OsuSetting.EditorSubmissionLoadInBrowserAfterSubmission, true);
}
protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup)
@ -461,5 +464,7 @@ namespace osu.Game.Configuration
BeatmapListingFeaturedArtistFilter,
ShowMobileDisclaimer,
EditorShowStoryboard,
EditorSubmissionNotifyOnDiscussionReplies,
EditorSubmissionLoadInBrowserAfterSubmission,
}
}

View File

@ -148,7 +148,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
{
base.LoadComplete();
Content.CornerRadius = 2;
Content.CornerRadius = 4;
Add(triangles = new TrianglesV2
{

View File

@ -0,0 +1,124 @@
// 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.Localisation;
namespace osu.Game.Localisation
{
public static class BeatmapSubmissionStrings
{
private const string prefix = @"osu.Game.Resources.Localisation.BeatmapSubmission";
/// <summary>
/// "Beatmap submission"
/// </summary>
public static LocalisableString BeatmapSubmissionTitle => new TranslatableString(getKey(@"beatmap_submission_title"), @"Beatmap submission");
/// <summary>
/// "Share your beatmap with the world!"
/// </summary>
public static LocalisableString BeatmapSubmissionDescription => new TranslatableString(getKey(@"beatmap_submission_description"), @"Share your beatmap with the world!");
/// <summary>
/// "Content permissions"
/// </summary>
public static LocalisableString ContentPermissions => new TranslatableString(getKey(@"content_permissions"), @"Content permissions");
/// <summary>
/// "I understand"
/// </summary>
public static LocalisableString ContentPermissionsAcknowledgement => new TranslatableString(getKey(@"content_permissions_acknowledgement"), @"I understand");
/// <summary>
/// "Frequently asked questions"
/// </summary>
public static LocalisableString FrequentlyAskedQuestions => new TranslatableString(getKey(@"frequently_asked_questions"), @"Frequently asked questions");
/// <summary>
/// "Submission settings"
/// </summary>
public static LocalisableString SubmissionSettings => new TranslatableString(getKey(@"submission_settings"), @"Submission settings");
/// <summary>
/// "Before you continue, we ask you to check whether the content you are uploading has been cleared for upload. Please understand that you are responsible for the content you upload to the platform and if in doubt, should ask permission from the creators before uploading!"
/// </summary>
public static LocalisableString ContentPermissionsDisclaimer => new TranslatableString(getKey(@"content_permissions_disclaimer"), @"Before you continue, we ask you to check whether the content you are uploading has been cleared for upload. Please understand that you are responsible for the content you upload to the platform and if in doubt, should ask permission from the creators before uploading!");
/// <summary>
/// "Check the content usage guidelines for more information"
/// </summary>
public static LocalisableString CheckContentUsageGuidelines => new TranslatableString(getKey(@"check_content_usage_guidelines"), @"Check the content usage guidelines for more information");
/// <summary>
/// "Beatmap ranking criteria"
/// </summary>
public static LocalisableString BeatmapRankingCriteria => new TranslatableString(getKey(@"beatmap_ranking_criteria"), @"Beatmap ranking criteria");
/// <summary>
/// "Not sure you meet the guidelines? Check the list and speed up the ranking process!"
/// </summary>
public static LocalisableString BeatmapRankingCriteriaDescription => new TranslatableString(getKey(@"beatmap_ranking_criteria_description"), @"Not sure you meet the guidelines? Check the list and speed up the ranking process!");
/// <summary>
/// "Submission process"
/// </summary>
public static LocalisableString SubmissionProcess => new TranslatableString(getKey(@"submission_process"), @"Submission process");
/// <summary>
/// "Unsure about the submission process? Check out the wiki entry!"
/// </summary>
public static LocalisableString SubmissionProcessDescription => new TranslatableString(getKey(@"submission_process_description"), @"Unsure about the submission process? Check out the wiki entry!");
/// <summary>
/// "Mapping help forum"
/// </summary>
public static LocalisableString MappingHelpForum => new TranslatableString(getKey(@"mapping_help_forum"), @"Mapping help forum");
/// <summary>
/// "Got some questions about mapping and submission? Ask them in the forums!"
/// </summary>
public static LocalisableString MappingHelpForumDescription => new TranslatableString(getKey(@"mapping_help_forum_description"), @"Got some questions about mapping and submission? Ask them in the forums!");
/// <summary>
/// "Modding queues forum"
/// </summary>
public static LocalisableString ModdingQueuesForum => new TranslatableString(getKey(@"modding_queues_forum"), @"Modding queues forum");
/// <summary>
/// "Having trouble getting feedback? Why not ask in a mod queue!"
/// </summary>
public static LocalisableString ModdingQueuesForumDescription => new TranslatableString(getKey(@"modding_queues_forum_description"), @"Having trouble getting feedback? Why not ask in a mod queue!");
/// <summary>
/// "Where would you like to post your beatmap?"
/// </summary>
public static LocalisableString BeatmapSubmissionTargetCaption => new TranslatableString(getKey(@"beatmap_submission_target_caption"), @"Where would you like to post your beatmap?");
/// <summary>
/// "Works in Progress / Help (incomplete, not ready for ranking)"
/// </summary>
public static LocalisableString BeatmapSubmissionTargetWIP => new TranslatableString(getKey(@"beatmap_submission_target_wip"), @"Works in Progress / Help (incomplete, not ready for ranking)");
/// <summary>
/// "Pending (complete, ready for ranking)"
/// </summary>
public static LocalisableString BeatmapSubmissionTargetPending => new TranslatableString(getKey(@"beatmap_submission_target_pending"), @"Pending (complete, ready for ranking)");
/// <summary>
/// "Receive notifications for discussion replies"
/// </summary>
public static LocalisableString NotifyOnDiscussionReplies => new TranslatableString(getKey(@"notify_for_discussion_replies"), @"Receive notifications for discussion replies");
/// <summary>
/// "Load in browser after submission"
/// </summary>
public static LocalisableString LoadInBrowserAfterSubmission => new TranslatableString(getKey(@"load_in_browser_after_submission"), @"Load in browser after submission");
/// <summary>
/// "Note: In order to make it possible for users of all osu! versions to enjoy your beatmap, it will be exported in a backwards-compatible format. While we have made efforts to ensure that that process keeps the beatmap playable in its intended form, some data related to features that previous versions of osu! do not support may be lost."
/// </summary>
public static LocalisableString LegacyExportDisclaimer => new TranslatableString(getKey(@"legacy_export_disclaimer"), @"Note: In order to make it possible for users of all osu! versions to enjoy your beatmap, it will be exported in a backwards-compatible format. While we have made efforts to ensure that that process keeps the beatmap playable in its intended form, some data related to features that previous versions of osu! do not support may be lost.");
private static string getKey(string key) => $@"{prefix}:{key}";
}
}

View File

@ -65,6 +65,8 @@ namespace osu.Game.Overlays.FirstRunSetup
};
}
public override LocalisableString? NextStepText => FirstRunSetupOverlayStrings.GetStarted;
private partial class LanguageSelectionFlow : FillFlowContainer
{
private Bindable<Language> language = null!;

View File

@ -227,7 +227,7 @@ namespace osu.Game.Overlays
updateButtons();
}
private void updateButtons() => DisplayedFooterContent?.UpdateButtons(CurrentStepIndex, steps);
private void updateButtons() => DisplayedFooterContent?.UpdateButtons(CurrentStepIndex, CurrentScreen, steps);
public partial class WizardFooterContent : VisibilityContainer
{
@ -248,24 +248,23 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.X,
Width = 1,
Text = FirstRunSetupOverlayStrings.GetStarted,
DarkerColour = colourProvider.Colour2,
LighterColour = colourProvider.Colour1,
DarkerColour = colourProvider.Colour3,
LighterColour = colourProvider.Colour2,
Action = () => ShowNextStep?.Invoke(),
};
}
public void UpdateButtons(int? currentStep, IReadOnlyList<Type> steps)
public void UpdateButtons(int? currentStep, WizardScreen? currentScreen, IReadOnlyList<Type> steps)
{
NextButton.Enabled.Value = currentStep != null;
if (currentStep == null)
return;
bool isFirstStep = currentStep == 0;
bool isLastStep = currentStep == steps.Count - 1;
if (isFirstStep)
NextButton.Text = FirstRunSetupOverlayStrings.GetStarted;
if (currentScreen?.NextStepText != null)
NextButton.Text = currentScreen.NextStepText.Value;
else
{
NextButton.Text = isLastStep

View File

@ -7,6 +7,7 @@ using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Localisation;
using osu.Framework.Screens;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
@ -102,5 +103,7 @@ namespace osu.Game.Overlays
base.OnSuspending(e);
}
public virtual LocalisableString? NextStepText => null;
}
}

View File

@ -0,0 +1,28 @@
// 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.Game.Overlays;
using osu.Game.Localisation;
namespace osu.Game.Screens.Edit.Submission
{
public partial class BeatmapSubmissionOverlay : WizardOverlay
{
public BeatmapSubmissionOverlay()
: base(OverlayColourScheme.Aquamarine)
{
}
[BackgroundDependencyLoader]
private void load()
{
AddStep<ScreenContentPermissions>();
AddStep<ScreenFrequentlyAskedQuestions>();
AddStep<ScreenSubmissionSettings>();
Header.Title = BeatmapSubmissionStrings.BeatmapSubmissionTitle;
Header.Description = BeatmapSubmissionStrings.BeatmapSubmissionDescription;
}
}
}

View File

@ -0,0 +1,44 @@
// 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.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays;
namespace osu.Game.Screens.Edit.Submission
{
[LocalisableDescription(typeof(BeatmapSubmissionStrings), nameof(BeatmapSubmissionStrings.ContentPermissions))]
public partial class ScreenContentPermissions : WizardScreen
{
[BackgroundDependencyLoader]
private void load(OsuGame? game)
{
Content.AddRange(new Drawable[]
{
new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: CONTENT_FONT_SIZE))
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = BeatmapSubmissionStrings.ContentPermissionsDisclaimer,
},
new RoundedButton
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Width = 450,
Text = BeatmapSubmissionStrings.CheckContentUsageGuidelines,
Action = () => game?.ShowWiki(@"Rules/Content_usage_permissions"),
},
});
}
public override LocalisableString? NextStepText => BeatmapSubmissionStrings.ContentPermissionsAcknowledgement;
}
}

View File

@ -0,0 +1,62 @@
// 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.Containers;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Online.API;
using osu.Game.Overlays;
using osuTK;
namespace osu.Game.Screens.Edit.Submission
{
[LocalisableDescription(typeof(BeatmapSubmissionStrings), nameof(BeatmapSubmissionStrings.FrequentlyAskedQuestions))]
public partial class ScreenFrequentlyAskedQuestions : WizardScreen
{
[BackgroundDependencyLoader]
private void load(OsuGame? game, IAPIProvider api)
{
Content.Add(new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(5),
Children = new Drawable[]
{
new FormButton
{
RelativeSizeAxes = Axes.X,
Caption = BeatmapSubmissionStrings.BeatmapRankingCriteriaDescription,
ButtonText = BeatmapSubmissionStrings.BeatmapRankingCriteria,
Action = () => game?.ShowWiki(@"Ranking_Criteria"),
},
new FormButton
{
RelativeSizeAxes = Axes.X,
Caption = BeatmapSubmissionStrings.SubmissionProcessDescription,
ButtonText = BeatmapSubmissionStrings.SubmissionProcess,
Action = () => game?.ShowWiki(@"Beatmap_ranking_procedure"),
},
new FormButton
{
RelativeSizeAxes = Axes.X,
Caption = BeatmapSubmissionStrings.MappingHelpForumDescription,
ButtonText = BeatmapSubmissionStrings.MappingHelpForum,
Action = () => game?.OpenUrlExternally($@"{api.WebsiteRootUrl}/community/forums/56"),
},
new FormButton
{
RelativeSizeAxes = Axes.X,
Caption = BeatmapSubmissionStrings.ModdingQueuesForumDescription,
ButtonText = BeatmapSubmissionStrings.ModdingQueuesForum,
Action = () => game?.OpenUrlExternally($@"{api.WebsiteRootUrl}/community/forums/60"),
},
},
});
}
}
}

View File

@ -0,0 +1,73 @@
// 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.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays;
using osuTK;
namespace osu.Game.Screens.Edit.Submission
{
[LocalisableDescription(typeof(BeatmapSubmissionStrings), nameof(BeatmapSubmissionStrings.SubmissionSettings))]
public partial class ScreenSubmissionSettings : WizardScreen
{
private readonly BindableBool notifyOnDiscussionReplies = new BindableBool();
private readonly BindableBool loadInBrowserAfterSubmission = new BindableBool();
[BackgroundDependencyLoader]
private void load(OsuConfigManager configManager, OsuColour colours)
{
configManager.BindWith(OsuSetting.EditorSubmissionNotifyOnDiscussionReplies, notifyOnDiscussionReplies);
configManager.BindWith(OsuSetting.EditorSubmissionLoadInBrowserAfterSubmission, loadInBrowserAfterSubmission);
Content.Add(new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(5),
Children = new Drawable[]
{
new FormEnumDropdown<BeatmapSubmissionTarget>
{
RelativeSizeAxes = Axes.X,
Caption = BeatmapSubmissionStrings.BeatmapSubmissionTargetCaption,
},
new FormCheckBox
{
Caption = BeatmapSubmissionStrings.NotifyOnDiscussionReplies,
Current = notifyOnDiscussionReplies,
},
new FormCheckBox
{
Caption = BeatmapSubmissionStrings.LoadInBrowserAfterSubmission,
Current = loadInBrowserAfterSubmission,
},
new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: CONTENT_FONT_SIZE, weight: FontWeight.Bold))
{
RelativeSizeAxes = Axes.X,
Colour = colours.Orange1,
Text = BeatmapSubmissionStrings.LegacyExportDisclaimer,
Padding = new MarginPadding { Top = 20 }
},
}
});
}
private enum BeatmapSubmissionTarget
{
[LocalisableDescription(typeof(BeatmapSubmissionStrings), nameof(BeatmapSubmissionStrings.BeatmapSubmissionTargetWIP))]
WIP,
[LocalisableDescription(typeof(BeatmapSubmissionStrings), nameof(BeatmapSubmissionStrings.BeatmapSubmissionTargetPending))]
Pending,
}
}
}