Merge branch 'master' into collection-database

This commit is contained in:
Dean Herbert
2020-09-09 22:59:46 +09:00
committed by GitHub
29 changed files with 155 additions and 56 deletions

View File

@ -1,6 +1,8 @@
// 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.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Mania.Edit.Blueprints; using osu.Game.Rulesets.Mania.Edit.Blueprints;
@ -14,6 +16,8 @@ namespace osu.Game.Rulesets.Mania.Edit
{ {
} }
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
public override PlacementBlueprint CreatePlacementBlueprint() => new HoldNotePlacementBlueprint(); public override PlacementBlueprint CreatePlacementBlueprint() => new HoldNotePlacementBlueprint();
} }
} }

View File

@ -1,6 +1,8 @@
// 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.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Mania.Edit.Blueprints; using osu.Game.Rulesets.Mania.Edit.Blueprints;
@ -15,6 +17,8 @@ namespace osu.Game.Rulesets.Mania.Edit
{ {
} }
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
public override PlacementBlueprint CreatePlacementBlueprint() => new NotePlacementBlueprint(); public override PlacementBlueprint CreatePlacementBlueprint() => new NotePlacementBlueprint();
} }
} }

View File

@ -1,6 +1,8 @@
// 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.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
@ -15,6 +17,8 @@ namespace osu.Game.Rulesets.Osu.Edit
{ {
} }
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
public override PlacementBlueprint CreatePlacementBlueprint() => new HitCirclePlacementBlueprint(); public override PlacementBlueprint CreatePlacementBlueprint() => new HitCirclePlacementBlueprint();
} }
} }

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Caching; using osu.Framework.Caching;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -38,6 +39,13 @@ namespace osu.Game.Rulesets.Osu.Edit
new SpinnerCompositionTool() new SpinnerCompositionTool()
}; };
private readonly BindableBool distanceSnapToggle = new BindableBool(true) { Description = "Distance Snap" };
protected override IEnumerable<BindableBool> Toggles => new[]
{
distanceSnapToggle
};
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
@ -45,6 +53,7 @@ namespace osu.Game.Rulesets.Osu.Edit
EditorBeatmap.SelectedHitObjects.CollectionChanged += (_, __) => updateDistanceSnapGrid(); EditorBeatmap.SelectedHitObjects.CollectionChanged += (_, __) => updateDistanceSnapGrid();
EditorBeatmap.PlacementObject.ValueChanged += _ => updateDistanceSnapGrid(); EditorBeatmap.PlacementObject.ValueChanged += _ => updateDistanceSnapGrid();
distanceSnapToggle.ValueChanged += _ => updateDistanceSnapGrid();
} }
protected override ComposeBlueprintContainer CreateBlueprintContainer(IEnumerable<DrawableHitObject> hitObjects) protected override ComposeBlueprintContainer CreateBlueprintContainer(IEnumerable<DrawableHitObject> hitObjects)
@ -87,6 +96,10 @@ namespace osu.Game.Rulesets.Osu.Edit
{ {
distanceSnapGridContainer.Clear(); distanceSnapGridContainer.Clear();
distanceSnapGridCache.Invalidate(); distanceSnapGridCache.Invalidate();
distanceSnapGrid = null;
if (!distanceSnapToggle.Value)
return;
switch (BlueprintContainer.CurrentTool) switch (BlueprintContainer.CurrentTool)
{ {

View File

@ -1,6 +1,8 @@
// 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.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders;
@ -15,6 +17,8 @@ namespace osu.Game.Rulesets.Osu.Edit
{ {
} }
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
public override PlacementBlueprint CreatePlacementBlueprint() => new SliderPlacementBlueprint(); public override PlacementBlueprint CreatePlacementBlueprint() => new SliderPlacementBlueprint();
} }
} }

View File

@ -1,6 +1,8 @@
// 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.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners; using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners;
@ -15,6 +17,8 @@ namespace osu.Game.Rulesets.Osu.Edit
{ {
} }
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners);
public override PlacementBlueprint CreatePlacementBlueprint() => new SpinnerPlacementBlueprint(); public override PlacementBlueprint CreatePlacementBlueprint() => new SpinnerPlacementBlueprint();
} }
} }

View File

@ -1,6 +1,8 @@
// 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.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Taiko.Edit.Blueprints; using osu.Game.Rulesets.Taiko.Edit.Blueprints;
@ -15,6 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Edit
{ {
} }
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
public override PlacementBlueprint CreatePlacementBlueprint() => new DrumRollPlacementBlueprint(); public override PlacementBlueprint CreatePlacementBlueprint() => new DrumRollPlacementBlueprint();
} }
} }

View File

@ -1,6 +1,8 @@
// 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.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Taiko.Edit.Blueprints; using osu.Game.Rulesets.Taiko.Edit.Blueprints;
@ -15,6 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Edit
{ {
} }
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
public override PlacementBlueprint CreatePlacementBlueprint() => new HitPlacementBlueprint(); public override PlacementBlueprint CreatePlacementBlueprint() => new HitPlacementBlueprint();
} }
} }

View File

@ -1,6 +1,8 @@
// 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.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Taiko.Edit.Blueprints; using osu.Game.Rulesets.Taiko.Edit.Blueprints;
@ -15,6 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Edit
{ {
} }
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners);
public override PlacementBlueprint CreatePlacementBlueprint() => new SwellPlacementBlueprint(); public override PlacementBlueprint CreatePlacementBlueprint() => new SwellPlacementBlueprint();
} }
} }

View File

@ -3,6 +3,7 @@
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Screens.Edit.Components.RadioButtons; using osu.Game.Screens.Edit.Components.RadioButtons;
namespace osu.Game.Tests.Visual.Editing namespace osu.Game.Tests.Visual.Editing
@ -22,7 +23,7 @@ namespace osu.Game.Tests.Visual.Editing
{ {
new RadioButton("Item 1", () => { }), new RadioButton("Item 1", () => { }),
new RadioButton("Item 2", () => { }), new RadioButton("Item 2", () => { }),
new RadioButton("Item 3", () => { }), new RadioButton("Item 3", () => { }, () => new SpriteIcon { Icon = FontAwesome.Regular.Angry }),
new RadioButton("Item 4", () => { }), new RadioButton("Item 4", () => { }),
new RadioButton("Item 5", () => { }) new RadioButton("Item 5", () => { })
} }

View File

@ -48,7 +48,10 @@ namespace osu.Game.Tests.Visual.Gameplay
private class ExampleContainer : PlayerSettingsGroup private class ExampleContainer : PlayerSettingsGroup
{ {
protected override string Title => @"example"; public ExampleContainer()
: base("example")
{
}
} }
} }
} }

View File

@ -20,8 +20,6 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
{ {
private const int padding = 10; private const int padding = 10;
protected override string Title => @"ladder";
private SettingsDropdown<TournamentRound> roundDropdown; private SettingsDropdown<TournamentRound> roundDropdown;
private PlayerCheckbox losersCheckbox; private PlayerCheckbox losersCheckbox;
private DateTextBox dateTimeBox; private DateTextBox dateTimeBox;
@ -34,6 +32,11 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
[Resolved] [Resolved]
private LadderInfo ladderInfo { get; set; } private LadderInfo ladderInfo { get; set; }
public LadderEditorSettings()
: base("ladder")
{
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {

View File

@ -66,12 +66,14 @@ namespace osu.Game.Beatmaps
private readonly RulesetStore rulesets; private readonly RulesetStore rulesets;
private readonly BeatmapStore beatmaps; private readonly BeatmapStore beatmaps;
private readonly AudioManager audioManager; private readonly AudioManager audioManager;
private readonly BeatmapOnlineLookupQueue onlineLookupQueue;
private readonly TextureStore textureStore; private readonly TextureStore textureStore;
private readonly ITrackStore trackStore; private readonly ITrackStore trackStore;
[CanBeNull]
private readonly BeatmapOnlineLookupQueue onlineLookupQueue;
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, GameHost host = null, public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, GameHost host = null,
WorkingBeatmap defaultBeatmap = null) WorkingBeatmap defaultBeatmap = null, bool performOnlineLookups = false)
: base(storage, contextFactory, api, new BeatmapStore(contextFactory), host) : base(storage, contextFactory, api, new BeatmapStore(contextFactory), host)
{ {
this.rulesets = rulesets; this.rulesets = rulesets;
@ -85,7 +87,8 @@ namespace osu.Game.Beatmaps
beatmaps.ItemRemoved += removeWorkingCache; beatmaps.ItemRemoved += removeWorkingCache;
beatmaps.ItemUpdated += removeWorkingCache; beatmaps.ItemUpdated += removeWorkingCache;
onlineLookupQueue = new BeatmapOnlineLookupQueue(api, storage); if (performOnlineLookups)
onlineLookupQueue = new BeatmapOnlineLookupQueue(api, storage);
textureStore = new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)); textureStore = new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store));
trackStore = audioManager.GetTrackStore(Files.Store); trackStore = audioManager.GetTrackStore(Files.Store);
@ -142,7 +145,8 @@ namespace osu.Game.Beatmaps
bool hadOnlineBeatmapIDs = beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID > 0); bool hadOnlineBeatmapIDs = beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID > 0);
await onlineLookupQueue.UpdateAsync(beatmapSet, cancellationToken); if (onlineLookupQueue != null)
await onlineLookupQueue.UpdateAsync(beatmapSet, cancellationToken);
// ensure at least one beatmap was able to retrieve or keep an online ID, else drop the set ID. // ensure at least one beatmap was able to retrieve or keep an online ID, else drop the set ID.
if (hadOnlineBeatmapIDs && !beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID > 0)) if (hadOnlineBeatmapIDs && !beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID > 0))
@ -231,7 +235,7 @@ namespace osu.Game.Beatmaps
/// <param name="beatmapSkin">The beatmap <see cref="ISkin"/> content to write, null if to be omitted.</param> /// <param name="beatmapSkin">The beatmap <see cref="ISkin"/> content to write, null if to be omitted.</param>
public void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin beatmapSkin = null) public void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin beatmapSkin = null)
{ {
var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); var setInfo = info.BeatmapSet;
using (var stream = new MemoryStream()) using (var stream = new MemoryStream())
{ {

View File

@ -103,6 +103,8 @@ namespace osu.Game.Graphics.Containers
{ {
} }
private bool playedPopInSound;
protected override void UpdateState(ValueChangedEvent<Visibility> state) protected override void UpdateState(ValueChangedEvent<Visibility> state)
{ {
switch (state.NewValue) switch (state.NewValue)
@ -110,16 +112,24 @@ namespace osu.Game.Graphics.Containers
case Visibility.Visible: case Visibility.Visible:
if (OverlayActivationMode.Value == OverlayActivation.Disabled) if (OverlayActivationMode.Value == OverlayActivation.Disabled)
{ {
// todo: visual/audible feedback that this operation could not complete.
State.Value = Visibility.Hidden; State.Value = Visibility.Hidden;
return; return;
} }
samplePopIn?.Play(); samplePopIn?.Play();
playedPopInSound = true;
if (BlockScreenWideMouse && DimMainContent) game?.AddBlockingOverlay(this); if (BlockScreenWideMouse && DimMainContent) game?.AddBlockingOverlay(this);
break; break;
case Visibility.Hidden: case Visibility.Hidden:
samplePopOut?.Play(); if (playedPopInSound)
{
samplePopOut?.Play();
playedPopInSound = false;
}
if (BlockScreenWideMouse) game?.RemoveBlockingOverlay(this); if (BlockScreenWideMouse) game?.RemoveBlockingOverlay(this);
break; break;
} }

View File

@ -9,16 +9,20 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface namespace osu.Game.Graphics.UserInterface
{ {
public abstract class RollingCounter<T> : Container public abstract class RollingCounter<T> : Container, IHasCurrentValue<T>
where T : struct, IEquatable<T> where T : struct, IEquatable<T>
{ {
/// <summary> private readonly BindableWithCurrent<T> current = new BindableWithCurrent<T>();
/// The current value.
/// </summary> public Bindable<T> Current
public Bindable<T> Current = new Bindable<T>(); {
get => current.Current;
set => current.Current = value;
}
private SpriteText displayedCountSpriteText; private SpriteText displayedCountSpriteText;

View File

@ -56,13 +56,14 @@ namespace osu.Game.Online.Leaderboards
scrollFlow?.FadeOut(fade_duration, Easing.OutQuint).Expire(); scrollFlow?.FadeOut(fade_duration, Easing.OutQuint).Expire();
scrollFlow = null; scrollFlow = null;
loading.Hide();
showScoresDelegate?.Cancel(); showScoresDelegate?.Cancel();
showScoresCancellationSource?.Cancel(); showScoresCancellationSource?.Cancel();
if (scores == null || !scores.Any()) if (scores == null || !scores.Any())
{
loading.Hide();
return; return;
}
// ensure placeholder is hidden when displaying scores // ensure placeholder is hidden when displaying scores
PlaceholderState = PlaceholderState.Successful; PlaceholderState = PlaceholderState.Successful;
@ -84,6 +85,7 @@ namespace osu.Game.Online.Leaderboards
} }
scrollContainer.ScrollTo(0f, false); scrollContainer.ScrollTo(0f, false);
loading.Hide();
}, (showScoresCancellationSource = new CancellationTokenSource()).Token)); }, (showScoresCancellationSource = new CancellationTokenSource()).Token));
} }
} }

View File

@ -198,7 +198,7 @@ namespace osu.Game
// ordering is important here to ensure foreign keys rules are not broken in ModelStore.Cleanup() // ordering is important here to ensure foreign keys rules are not broken in ModelStore.Cleanup()
dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Storage, API, contextFactory, Host)); dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Storage, API, contextFactory, Host));
dependencies.Cache(BeatmapManager = new BeatmapManager(Storage, contextFactory, RulesetStore, API, Audio, Host, defaultBeatmap)); dependencies.Cache(BeatmapManager = new BeatmapManager(Storage, contextFactory, RulesetStore, API, Audio, Host, defaultBeatmap, true));
// this should likely be moved to ArchiveModelManager when another case appers where it is necessary // this should likely be moved to ArchiveModelManager when another case appers where it is necessary
// to have inter-dependent model managers. this could be obtained with an IHasForeign<T> interface to // to have inter-dependent model managers. this could be obtained with an IHasForeign<T> interface to

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Input; using osu.Framework.Input;
@ -13,6 +14,7 @@ using osu.Framework.Input.Events;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Configuration;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
@ -92,9 +94,18 @@ namespace osu.Game.Rulesets.Edit
Name = "Sidebar", Name = "Sidebar",
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Right = 10 }, Padding = new MarginPadding { Right = 10 },
Spacing = new Vector2(10),
Children = new Drawable[] Children = new Drawable[]
{ {
new ToolboxGroup { Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } } new ToolboxGroup("toolbox") { Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } },
new ToolboxGroup("toggles")
{
ChildrenEnumerable = Toggles.Select(b => new SettingsCheckbox
{
Bindable = b,
LabelText = b?.Description ?? "unknown"
})
}
} }
}, },
new Container new Container
@ -126,7 +137,7 @@ namespace osu.Game.Rulesets.Edit
toolboxCollection.Items = CompositionTools toolboxCollection.Items = CompositionTools
.Prepend(new SelectTool()) .Prepend(new SelectTool())
.Select(t => new RadioButton(t.Name, () => toolSelected(t))) .Select(t => new RadioButton(t.Name, () => toolSelected(t), t.CreateIcon))
.ToList(); .ToList();
setSelectTool(); setSelectTool();
@ -156,6 +167,12 @@ namespace osu.Game.Rulesets.Edit
/// </remarks> /// </remarks>
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; } protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
/// <summary>
/// A collection of toggles which will be displayed to the user.
/// The display name will be decided by <see cref="Bindable{T}.Description"/>.
/// </summary>
protected virtual IEnumerable<BindableBool> Toggles => Enumerable.Empty<BindableBool>();
/// <summary> /// <summary>
/// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic. /// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic.
/// </summary> /// </summary>

View File

@ -8,9 +8,8 @@ namespace osu.Game.Rulesets.Edit
{ {
public class ToolboxGroup : PlayerSettingsGroup public class ToolboxGroup : PlayerSettingsGroup
{ {
protected override string Title => "toolbox"; public ToolboxGroup(string title)
: base(title)
public ToolboxGroup()
{ {
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
Width = 1; Width = 1;

View File

@ -1,6 +1,8 @@
// 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.Graphics;
namespace osu.Game.Rulesets.Edit.Tools namespace osu.Game.Rulesets.Edit.Tools
{ {
public abstract class HitObjectCompositionTool public abstract class HitObjectCompositionTool
@ -14,6 +16,8 @@ namespace osu.Game.Rulesets.Edit.Tools
public abstract PlacementBlueprint CreatePlacementBlueprint(); public abstract PlacementBlueprint CreatePlacementBlueprint();
public virtual Drawable CreateIcon() => null;
public override string ToString() => Name; public override string ToString() => Name;
} }
} }

View File

@ -1,6 +1,9 @@
// 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.Graphics;
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Rulesets.Edit.Tools namespace osu.Game.Rulesets.Edit.Tools
{ {
public class SelectTool : HitObjectCompositionTool public class SelectTool : HitObjectCompositionTool
@ -10,6 +13,8 @@ namespace osu.Game.Rulesets.Edit.Tools
{ {
} }
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.Solid.MousePointer };
public override PlacementBlueprint CreatePlacementBlueprint() => null; public override PlacementBlueprint CreatePlacementBlueprint() => null;
} }
} }

View File

@ -5,7 +5,6 @@ using System;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
@ -29,7 +28,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
private Color4 selectedBackgroundColour; private Color4 selectedBackgroundColour;
private Color4 selectedBubbleColour; private Color4 selectedBubbleColour;
private readonly Drawable bubble; private Drawable icon;
private readonly RadioButton button; private readonly RadioButton button;
public DrawableRadioButton(RadioButton button) public DrawableRadioButton(RadioButton button)
@ -40,19 +39,6 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
Action = button.Select; Action = button.Select;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
bubble = new CircularContainer
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Scale = new Vector2(0.5f),
X = 10,
Masking = true,
Blending = BlendingParameters.Additive,
Child = new Box { RelativeSizeAxes = Axes.Both }
};
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -73,7 +59,14 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
Colour = Color4.Black.Opacity(0.5f) Colour = Color4.Black.Opacity(0.5f)
}; };
Add(bubble); Add(icon = (button.CreateIcon?.Invoke() ?? new Circle()).With(b =>
{
b.Blending = BlendingParameters.Additive;
b.Anchor = Anchor.CentreLeft;
b.Origin = Anchor.CentreLeft;
b.Size = new Vector2(20);
b.X = 10;
}));
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -96,7 +89,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
return; return;
BackgroundColour = button.Selected.Value ? selectedBackgroundColour : defaultBackgroundColour; BackgroundColour = button.Selected.Value ? selectedBackgroundColour : defaultBackgroundColour;
bubble.Colour = button.Selected.Value ? selectedBubbleColour : defaultBubbleColour; icon.Colour = button.Selected.Value ? selectedBubbleColour : defaultBubbleColour;
} }
protected override SpriteText CreateText() => new OsuSpriteText protected override SpriteText CreateText() => new OsuSpriteText

View File

@ -3,6 +3,7 @@
using System; using System;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics;
namespace osu.Game.Screens.Edit.Components.RadioButtons namespace osu.Game.Screens.Edit.Components.RadioButtons
{ {
@ -19,11 +20,17 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
/// </summary> /// </summary>
public object Item; public object Item;
/// <summary>
/// A function which creates a drawable icon to represent this item. If null, a sane default should be used.
/// </summary>
public readonly Func<Drawable> CreateIcon;
private readonly Action action; private readonly Action action;
public RadioButton(object item, Action action) public RadioButton(object item, Action action, Func<Drawable> createIcon = null)
{ {
Item = item; Item = item;
CreateIcon = createIcon;
this.action = action; this.action = action;
Selected = new BindableBool(); Selected = new BindableBool();
} }

View File

@ -10,7 +10,10 @@ namespace osu.Game.Screens.Play.PlayerSettings
{ {
public class CollectionSettings : PlayerSettingsGroup public class CollectionSettings : PlayerSettingsGroup
{ {
protected override string Title => @"collections"; public CollectionSettings()
: base("collections")
{
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()

View File

@ -10,7 +10,10 @@ namespace osu.Game.Screens.Play.PlayerSettings
{ {
public class DiscussionSettings : PlayerSettingsGroup public class DiscussionSettings : PlayerSettingsGroup
{ {
protected override string Title => @"discussions"; public DiscussionSettings()
: base("discussions")
{
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config) private void load(OsuConfigManager config)

View File

@ -9,11 +9,10 @@ namespace osu.Game.Screens.Play.PlayerSettings
{ {
public class InputSettings : PlayerSettingsGroup public class InputSettings : PlayerSettingsGroup
{ {
protected override string Title => "Input settings";
private readonly PlayerCheckbox mouseButtonsCheckbox; private readonly PlayerCheckbox mouseButtonsCheckbox;
public InputSettings() public InputSettings()
: base("Input Settings")
{ {
Children = new Drawable[] Children = new Drawable[]
{ {

View File

@ -13,8 +13,6 @@ namespace osu.Game.Screens.Play.PlayerSettings
{ {
private const int padding = 10; private const int padding = 10;
protected override string Title => @"playback";
public readonly Bindable<double> UserPlaybackRate = new BindableDouble(1) public readonly Bindable<double> UserPlaybackRate = new BindableDouble(1)
{ {
Default = 1, Default = 1,
@ -28,6 +26,7 @@ namespace osu.Game.Screens.Play.PlayerSettings
private readonly OsuSpriteText multiplierText; private readonly OsuSpriteText multiplierText;
public PlaybackSettings() public PlaybackSettings()
: base("playback")
{ {
Children = new Drawable[] Children = new Drawable[]
{ {

View File

@ -17,11 +17,6 @@ namespace osu.Game.Screens.Play.PlayerSettings
{ {
public abstract class PlayerSettingsGroup : Container public abstract class PlayerSettingsGroup : Container
{ {
/// <summary>
/// The title to be displayed in the header of this group.
/// </summary>
protected abstract string Title { get; }
private const float transition_duration = 250; private const float transition_duration = 250;
private const int container_width = 270; private const int container_width = 270;
private const int border_thickness = 2; private const int border_thickness = 2;
@ -58,7 +53,11 @@ namespace osu.Game.Screens.Play.PlayerSettings
private Color4 expandedColour; private Color4 expandedColour;
protected PlayerSettingsGroup() /// <summary>
/// Create a new instance.
/// </summary>
/// <param name="title">The title to be displayed in the header of this group.</param>
protected PlayerSettingsGroup(string title)
{ {
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
Width = container_width; Width = container_width;
@ -95,7 +94,7 @@ namespace osu.Game.Screens.Play.PlayerSettings
{ {
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Text = Title.ToUpperInvariant(), Text = title.ToUpperInvariant(),
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17), Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17),
Margin = new MarginPadding { Left = 10 }, Margin = new MarginPadding { Left = 10 },
}, },

View File

@ -10,8 +10,6 @@ namespace osu.Game.Screens.Play.PlayerSettings
{ {
public class VisualSettings : PlayerSettingsGroup public class VisualSettings : PlayerSettingsGroup
{ {
protected override string Title => "Visual settings";
private readonly PlayerSliderBar<double> dimSliderBar; private readonly PlayerSliderBar<double> dimSliderBar;
private readonly PlayerSliderBar<double> blurSliderBar; private readonly PlayerSliderBar<double> blurSliderBar;
private readonly PlayerCheckbox showStoryboardToggle; private readonly PlayerCheckbox showStoryboardToggle;
@ -19,6 +17,7 @@ namespace osu.Game.Screens.Play.PlayerSettings
private readonly PlayerCheckbox beatmapHitsoundsToggle; private readonly PlayerCheckbox beatmapHitsoundsToggle;
public VisualSettings() public VisualSettings()
: base("Visual Settings")
{ {
Children = new Drawable[] Children = new Drawable[]
{ {