mirror of
https://github.com/ppy/osu.git
synced 2025-02-06 21:02:59 +08:00
Merge branch 'master' into update-osu-stable-from-registry
This commit is contained in:
commit
fef81781e7
@ -88,10 +88,9 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
|||||||
switch (PlacementActive)
|
switch (PlacementActive)
|
||||||
{
|
{
|
||||||
case PlacementState.Waiting:
|
case PlacementState.Waiting:
|
||||||
if (!(result.Time is double snappedTime)) return;
|
|
||||||
|
|
||||||
HitObject.OriginalX = ToLocalSpace(result.ScreenSpacePosition).X;
|
HitObject.OriginalX = ToLocalSpace(result.ScreenSpacePosition).X;
|
||||||
HitObject.StartTime = snappedTime;
|
if (result.Time is double snappedTime)
|
||||||
|
HitObject.StartTime = snappedTime;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlacementState.Active:
|
case PlacementState.Active:
|
||||||
@ -107,21 +106,13 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
|||||||
Vector2 startPosition = CatchHitObjectUtils.GetStartPosition(HitObjectContainer, HitObject);
|
Vector2 startPosition = CatchHitObjectUtils.GetStartPosition(HitObjectContainer, HitObject);
|
||||||
editablePath.Position = nestedOutlineContainer.Position = scrollingPath.Position = startPosition;
|
editablePath.Position = nestedOutlineContainer.Position = scrollingPath.Position = startPosition;
|
||||||
|
|
||||||
updateHitObjectFromPath();
|
if (lastEditablePathId != editablePath.PathId)
|
||||||
}
|
editablePath.UpdateHitObjectFromPath(HitObject);
|
||||||
|
lastEditablePathId = editablePath.PathId;
|
||||||
|
|
||||||
private void updateHitObjectFromPath()
|
|
||||||
{
|
|
||||||
if (lastEditablePathId == editablePath.PathId)
|
|
||||||
return;
|
|
||||||
|
|
||||||
editablePath.UpdateHitObjectFromPath(HitObject);
|
|
||||||
ApplyDefaultsToHitObject();
|
ApplyDefaultsToHitObject();
|
||||||
|
|
||||||
scrollingPath.UpdatePathFrom(HitObjectContainer, HitObject);
|
scrollingPath.UpdatePathFrom(HitObjectContainer, HitObject);
|
||||||
nestedOutlineContainer.UpdateNestedObjectsFrom(HitObjectContainer, HitObject);
|
nestedOutlineContainer.UpdateNestedObjectsFrom(HitObjectContainer, HitObject);
|
||||||
|
|
||||||
lastEditablePathId = editablePath.PathId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private double positionToTime(float relativeYPosition)
|
private double positionToTime(float relativeYPosition)
|
||||||
|
@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
|
|
||||||
protected override Drawable CreateHitObjectInspector() => new CatchHitObjectInspector(DistanceSnapProvider);
|
protected override Drawable CreateHitObjectInspector() => new CatchHitObjectInspector(DistanceSnapProvider);
|
||||||
|
|
||||||
protected override IEnumerable<TernaryButton> CreateTernaryButtons()
|
protected override IEnumerable<DrawableTernaryButton> CreateTernaryButtons()
|
||||||
=> base.CreateTernaryButtons()
|
=> base.CreateTernaryButtons()
|
||||||
.Concat(DistanceSnapProvider.CreateTernaryButtons());
|
.Concat(DistanceSnapProvider.CreateTernaryButtons());
|
||||||
|
|
||||||
|
@ -53,9 +53,14 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
|
|
||||||
protected override Drawable CreateHitObjectInspector() => new OsuHitObjectInspector();
|
protected override Drawable CreateHitObjectInspector() => new OsuHitObjectInspector();
|
||||||
|
|
||||||
protected override IEnumerable<TernaryButton> CreateTernaryButtons()
|
protected override IEnumerable<DrawableTernaryButton> CreateTernaryButtons()
|
||||||
=> base.CreateTernaryButtons()
|
=> base.CreateTernaryButtons()
|
||||||
.Append(new TernaryButton(rectangularGridSnapToggle, "Grid Snap", () => new SpriteIcon { Icon = OsuIcon.EditorGridSnap }))
|
.Append(new DrawableTernaryButton
|
||||||
|
{
|
||||||
|
Current = rectangularGridSnapToggle,
|
||||||
|
Description = "Grid Snap",
|
||||||
|
CreateIcon = () => new SpriteIcon { Icon = OsuIcon.EditorGridSnap },
|
||||||
|
})
|
||||||
.Concat(DistanceSnapProvider.CreateTernaryButtons());
|
.Concat(DistanceSnapProvider.CreateTernaryButtons());
|
||||||
|
|
||||||
private BindableList<HitObject> selectedHitObjects;
|
private BindableList<HitObject> selectedHitObjects;
|
||||||
|
@ -7,16 +7,15 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Screens;
|
||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Screens.Edit.Components;
|
using osu.Game.Screens.Edit.Components;
|
||||||
@ -43,14 +42,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
|
|
||||||
private BeatmapSetInfo importedBeatmapSet;
|
private BeatmapSetInfo importedBeatmapSet;
|
||||||
|
|
||||||
private Bindable<float> editorDim;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuConfigManager config)
|
|
||||||
{
|
|
||||||
editorDim = config.GetBindable<float>(OsuSetting.EditorDim);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
{
|
{
|
||||||
AddStep("import test beatmap", () => importedBeatmapSet = BeatmapImportHelper.LoadOszIntoOsu(game).GetResultSafely());
|
AddStep("import test beatmap", () => importedBeatmapSet = BeatmapImportHelper.LoadOszIntoOsu(game).GetResultSafely());
|
||||||
@ -81,15 +72,7 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
AddUntilStep("player pushed", () => (editorPlayer = Stack.CurrentScreen as EditorPlayer) != null);
|
AddUntilStep("player pushed", () => (editorPlayer = Stack.CurrentScreen as EditorPlayer) != null);
|
||||||
AddStep("exit player", () => editorPlayer.Exit());
|
AddStep("exit player", () => editorPlayer.Exit());
|
||||||
AddUntilStep("current screen is editor", () => Stack.CurrentScreen is Editor);
|
AddUntilStep("current screen is editor", () => Stack.CurrentScreen is Editor);
|
||||||
AddUntilStep("background has correct params", () =>
|
AddUntilStep("background is correct", () => this.ChildrenOfType<BackgroundScreenStack>().Single().CurrentScreen is EditorBackgroundScreen);
|
||||||
{
|
|
||||||
// the test gameplay player's beatmap may be the "same" beatmap as the one being edited, *but* the `BeatmapInfo` references may differ
|
|
||||||
// due to the beatmap refetch logic ran on editor suspend.
|
|
||||||
// this test cares about checking the background belonging to the editor specifically, so check that using reference equality
|
|
||||||
// (as `.Equals()` cannot discern between the two, as they technically share the same database GUID).
|
|
||||||
var background = this.ChildrenOfType<BackgroundScreenBeatmap>().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo));
|
|
||||||
return background.DimWhenUserSettingsIgnored.Value == editorDim.Value && background.BlurAmount.Value == 0;
|
|
||||||
});
|
|
||||||
AddAssert("no mods selected", () => SelectedMods.Value.Count == 0);
|
AddAssert("no mods selected", () => SelectedMods.Value.Count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,15 +97,7 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
|
|
||||||
AddStep("exit player", () => editorPlayer.Exit());
|
AddStep("exit player", () => editorPlayer.Exit());
|
||||||
AddUntilStep("current screen is editor", () => Stack.CurrentScreen is Editor);
|
AddUntilStep("current screen is editor", () => Stack.CurrentScreen is Editor);
|
||||||
AddUntilStep("background has correct params", () =>
|
AddUntilStep("background is correct", () => this.ChildrenOfType<BackgroundScreenStack>().Single().CurrentScreen is EditorBackgroundScreen);
|
||||||
{
|
|
||||||
// the test gameplay player's beatmap may be the "same" beatmap as the one being edited, *but* the `BeatmapInfo` references may differ
|
|
||||||
// due to the beatmap refetch logic ran on editor suspend.
|
|
||||||
// this test cares about checking the background belonging to the editor specifically, so check that using reference equality
|
|
||||||
// (as `.Equals()` cannot discern between the two, as they technically share the same database GUID).
|
|
||||||
var background = this.ChildrenOfType<BackgroundScreenBeatmap>().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo));
|
|
||||||
return background.DimWhenUserSettingsIgnored.Value == editorDim.Value && background.BlurAmount.Value == 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep("start track", () => EditorClock.Start());
|
AddStep("start track", () => EditorClock.Start());
|
||||||
AddAssert("sample playback re-enabled", () => !Editor.SamplePlaybackDisabled.Value);
|
AddAssert("sample playback re-enabled", () => !Editor.SamplePlaybackDisabled.Value);
|
||||||
|
@ -220,6 +220,7 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
SetDefault(OsuSetting.AlwaysShowHoldForMenuButton, false);
|
SetDefault(OsuSetting.AlwaysShowHoldForMenuButton, false);
|
||||||
SetDefault(OsuSetting.AlwaysRequireHoldingForPause, false);
|
SetDefault(OsuSetting.AlwaysRequireHoldingForPause, false);
|
||||||
|
SetDefault(OsuSetting.EditorShowStoryboard, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup)
|
protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup)
|
||||||
@ -455,5 +456,6 @@ namespace osu.Game.Configuration
|
|||||||
MultiplayerShowInProgressFilter,
|
MultiplayerShowInProgressFilter,
|
||||||
BeatmapListingFeaturedArtistFilter,
|
BeatmapListingFeaturedArtistFilter,
|
||||||
ShowMobileDisclaimer,
|
ShowMobileDisclaimer,
|
||||||
|
EditorShowStoryboard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,9 +191,14 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<TernaryButton> CreateTernaryButtons() => new[]
|
public IEnumerable<DrawableTernaryButton> CreateTernaryButtons() => new[]
|
||||||
{
|
{
|
||||||
new TernaryButton(DistanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = OsuIcon.EditorDistanceSnap })
|
new DrawableTernaryButton
|
||||||
|
{
|
||||||
|
Current = DistanceSnapToggle,
|
||||||
|
Description = "Distance Snap",
|
||||||
|
CreateIcon = () => new SpriteIcon { Icon = OsuIcon.EditorDistanceSnap },
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public void HandleToggleViaKey(KeyboardEvent key)
|
public void HandleToggleViaKey(KeyboardEvent key)
|
||||||
|
@ -269,10 +269,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TernaryStates = CreateTernaryButtons().ToArray();
|
togglesCollection.AddRange(CreateTernaryButtons().ToArray());
|
||||||
togglesCollection.AddRange(TernaryStates.Select(b => new DrawableTernaryButton(b)));
|
|
||||||
|
|
||||||
sampleBankTogglesCollection.AddRange(BlueprintContainer.SampleBankTernaryStates.Zip(BlueprintContainer.SampleAdditionBankTernaryStates).Select(b => new SampleBankTernaryButton(b.First, b.Second)));
|
sampleBankTogglesCollection.AddRange(BlueprintContainer.SampleBankTernaryStates);
|
||||||
|
|
||||||
SetSelectTool();
|
SetSelectTool();
|
||||||
|
|
||||||
@ -368,15 +367,10 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected abstract IReadOnlyList<CompositionTool> CompositionTools { get; }
|
protected abstract IReadOnlyList<CompositionTool> CompositionTools { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A collection of states which will be displayed to the user in the toolbox.
|
|
||||||
/// </summary>
|
|
||||||
public TernaryButton[] TernaryStates { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create all ternary states required to be displayed to the user.
|
/// Create all ternary states required to be displayed to the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual IEnumerable<TernaryButton> CreateTernaryButtons() => BlueprintContainer.MainTernaryStates;
|
protected virtual IEnumerable<DrawableTernaryButton> CreateTernaryButtons() => BlueprintContainer.MainTernaryStates;
|
||||||
|
|
||||||
/// <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.
|
||||||
@ -437,7 +431,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
{
|
{
|
||||||
if (togglesCollection.ElementAtOrDefault(rightIndex) is DrawableTernaryButton button)
|
if (togglesCollection.ElementAtOrDefault(rightIndex) is DrawableTernaryButton button)
|
||||||
{
|
{
|
||||||
button.Button.Toggle();
|
button.Toggle();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,12 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
Spacing = new Vector2(0, 5),
|
Spacing = new Vector2(0, 5),
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
new DrawableTernaryButton(new TernaryButton(showSpeedChanges, "Show speed changes", () => new SpriteIcon { Icon = FontAwesome.Solid.TachometerAlt }))
|
new DrawableTernaryButton
|
||||||
|
{
|
||||||
|
Current = showSpeedChanges,
|
||||||
|
Description = "Show speed changes",
|
||||||
|
CreateIcon = () => new SpriteIcon { Icon = FontAwesome.Solid.TachometerAlt },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -101,18 +101,6 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reloads beatmap's background.
|
|
||||||
/// </summary>
|
|
||||||
public void RefreshBackground()
|
|
||||||
{
|
|
||||||
Schedule(() =>
|
|
||||||
{
|
|
||||||
cancellationSource?.Cancel();
|
|
||||||
LoadComponentAsync(new BeatmapBackground(beatmap), switchBackground, (cancellationSource = new CancellationTokenSource()).Token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void switchBackground(BeatmapBackground b)
|
private void switchBackground(BeatmapBackground b)
|
||||||
{
|
{
|
||||||
float newDepth = 0;
|
float newDepth = 0;
|
||||||
|
117
osu.Game/Screens/Backgrounds/EditorBackgroundScreen.cs
Normal file
117
osu.Game/Screens/Backgrounds/EditorBackgroundScreen.cs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Timing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Backgrounds;
|
||||||
|
using osu.Game.Storyboards.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Backgrounds
|
||||||
|
{
|
||||||
|
public partial class EditorBackgroundScreen : BackgroundScreen
|
||||||
|
{
|
||||||
|
private readonly WorkingBeatmap beatmap;
|
||||||
|
private readonly Container dimContainer;
|
||||||
|
|
||||||
|
private CancellationTokenSource? cancellationTokenSource;
|
||||||
|
private Bindable<float> dimLevel = null!;
|
||||||
|
private Bindable<bool> showStoryboard = null!;
|
||||||
|
|
||||||
|
private BeatmapBackground background = null!;
|
||||||
|
private Container storyboardContainer = null!;
|
||||||
|
|
||||||
|
private IFrameBasedClock? clockSource;
|
||||||
|
|
||||||
|
public EditorBackgroundScreen(WorkingBeatmap beatmap)
|
||||||
|
{
|
||||||
|
this.beatmap = beatmap;
|
||||||
|
|
||||||
|
InternalChild = dimContainer = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuConfigManager config)
|
||||||
|
{
|
||||||
|
dimContainer.AddRange(createContent());
|
||||||
|
background = dimContainer.OfType<BeatmapBackground>().Single();
|
||||||
|
storyboardContainer = dimContainer.OfType<Container>().Single();
|
||||||
|
|
||||||
|
dimLevel = config.GetBindable<float>(OsuSetting.EditorDim);
|
||||||
|
showStoryboard = config.GetBindable<bool>(OsuSetting.EditorShowStoryboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<Drawable> createContent() =>
|
||||||
|
[
|
||||||
|
new BeatmapBackground(beatmap) { RelativeSizeAxes = Axes.Both, },
|
||||||
|
// this kooky container nesting is here because the storyboard needs a custom clock
|
||||||
|
// but also needs it on an isolated-enough level that doesn't break screen stack expiry logic (which happens if the clock was put on `this`),
|
||||||
|
// or doesn't make it literally impossible to fade the storyboard in/out in real time (which happens if the fade transforms were to be applied directly to the storyboard).
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = new DrawableStoryboard(beatmap.Storyboard)
|
||||||
|
{
|
||||||
|
Clock = clockSource ?? Clock,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
dimLevel.BindValueChanged(_ => dimContainer.FadeColour(OsuColour.Gray(1 - dimLevel.Value), 500, Easing.OutQuint), true);
|
||||||
|
showStoryboard.BindValueChanged(_ => updateState());
|
||||||
|
updateState(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateState(double duration = 500)
|
||||||
|
{
|
||||||
|
storyboardContainer.FadeTo(showStoryboard.Value ? 1 : 0, duration, Easing.OutQuint);
|
||||||
|
// yes, this causes overdraw, but is also a (crude) fix for bad-looking transitions on screen entry
|
||||||
|
// caused by the previous background on the background stack poking out from under this one and then instantly fading out
|
||||||
|
background.FadeColour(beatmap.Storyboard.ReplacesBackground && showStoryboard.Value ? Colour4.Black : Colour4.White, duration, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeClockSource(IFrameBasedClock frameBasedClock)
|
||||||
|
{
|
||||||
|
clockSource = frameBasedClock;
|
||||||
|
if (IsLoaded)
|
||||||
|
storyboardContainer.Child.Clock = frameBasedClock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshBackground()
|
||||||
|
{
|
||||||
|
cancellationTokenSource?.Cancel();
|
||||||
|
LoadComponentsAsync(createContent(), loaded =>
|
||||||
|
{
|
||||||
|
dimContainer.Clear();
|
||||||
|
dimContainer.AddRange(loaded);
|
||||||
|
|
||||||
|
background = dimContainer.OfType<BeatmapBackground>().Single();
|
||||||
|
storyboardContainer = dimContainer.OfType<Container>().Single();
|
||||||
|
updateState(0);
|
||||||
|
}, (cancellationTokenSource ??= new CancellationTokenSource()).Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(BackgroundScreen? other)
|
||||||
|
{
|
||||||
|
if (other is not EditorBackgroundScreen otherBeatmapBackground)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return base.Equals(other) && beatmap == otherBeatmapBackground.beatmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,15 @@
|
|||||||
// 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;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -16,8 +19,29 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
||||||
{
|
{
|
||||||
public partial class DrawableTernaryButton : OsuButton, IHasTooltip
|
public partial class DrawableTernaryButton : OsuButton, IHasTooltip, IHasCurrentValue<TernaryState>
|
||||||
{
|
{
|
||||||
|
public Bindable<TernaryState> Current
|
||||||
|
{
|
||||||
|
get => current.Current;
|
||||||
|
set => current.Current = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly BindableWithCurrent<TernaryState> current = new BindableWithCurrent<TernaryState>();
|
||||||
|
|
||||||
|
public required LocalisableString Description
|
||||||
|
{
|
||||||
|
get => Text;
|
||||||
|
set => Text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalisableString TooltipText { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A function which creates a drawable icon to represent this item. If null, a sane default should be used.
|
||||||
|
/// </summary>
|
||||||
|
public Func<Drawable>? CreateIcon { get; init; }
|
||||||
|
|
||||||
private Color4 defaultBackgroundColour;
|
private Color4 defaultBackgroundColour;
|
||||||
private Color4 defaultIconColour;
|
private Color4 defaultIconColour;
|
||||||
private Color4 selectedBackgroundColour;
|
private Color4 selectedBackgroundColour;
|
||||||
@ -25,14 +49,8 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
|||||||
|
|
||||||
protected Drawable Icon { get; private set; } = null!;
|
protected Drawable Icon { get; private set; } = null!;
|
||||||
|
|
||||||
public readonly TernaryButton Button;
|
public DrawableTernaryButton()
|
||||||
|
|
||||||
public DrawableTernaryButton(TernaryButton button)
|
|
||||||
{
|
{
|
||||||
Button = button;
|
|
||||||
|
|
||||||
Text = button.Description;
|
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +63,7 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
|||||||
defaultIconColour = defaultBackgroundColour.Darken(0.5f);
|
defaultIconColour = defaultBackgroundColour.Darken(0.5f);
|
||||||
selectedIconColour = selectedBackgroundColour.Lighten(0.5f);
|
selectedIconColour = selectedBackgroundColour.Lighten(0.5f);
|
||||||
|
|
||||||
Add(Icon = (Button.CreateIcon?.Invoke() ?? new Circle()).With(b =>
|
Add(Icon = (CreateIcon?.Invoke() ?? new Circle()).With(b =>
|
||||||
{
|
{
|
||||||
b.Blending = BlendingParameters.Additive;
|
b.Blending = BlendingParameters.Additive;
|
||||||
b.Anchor = Anchor.CentreLeft;
|
b.Anchor = Anchor.CentreLeft;
|
||||||
@ -59,18 +77,32 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
Button.Bindable.BindValueChanged(_ => updateSelectionState(), true);
|
current.BindValueChanged(_ => updateSelectionState(), true);
|
||||||
Button.Enabled.BindTo(Enabled);
|
|
||||||
|
|
||||||
Action = onAction;
|
Action = onAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAction()
|
private void onAction()
|
||||||
{
|
{
|
||||||
if (!Button.Enabled.Value)
|
if (!Enabled.Value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Button.Toggle();
|
Toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Toggle()
|
||||||
|
{
|
||||||
|
switch (Current.Value)
|
||||||
|
{
|
||||||
|
case TernaryState.False:
|
||||||
|
case TernaryState.Indeterminate:
|
||||||
|
Current.Value = TernaryState.True;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TernaryState.True:
|
||||||
|
Current.Value = TernaryState.False;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSelectionState()
|
private void updateSelectionState()
|
||||||
@ -78,7 +110,7 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
|||||||
if (!IsLoaded)
|
if (!IsLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (Button.Bindable.Value)
|
switch (Current.Value)
|
||||||
{
|
{
|
||||||
case TernaryState.Indeterminate:
|
case TernaryState.Indeterminate:
|
||||||
Icon.Colour = selectedIconColour.Darken(0.5f);
|
Icon.Colour = selectedIconColour.Darken(0.5f);
|
||||||
@ -104,7 +136,5 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
|||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
X = 40f
|
X = 40f
|
||||||
};
|
};
|
||||||
|
|
||||||
public LocalisableString TooltipText => Button.Tooltip;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,32 @@
|
|||||||
// 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;
|
||||||
|
using Humanizer;
|
||||||
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.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
||||||
{
|
{
|
||||||
public partial class SampleBankTernaryButton : CompositeDrawable
|
public partial class SampleBankTernaryButton : CompositeDrawable
|
||||||
{
|
{
|
||||||
public readonly TernaryButton NormalButton;
|
public string BankName { get; }
|
||||||
public readonly TernaryButton AdditionsButton;
|
public Func<Drawable>? CreateIcon { get; init; }
|
||||||
|
|
||||||
public SampleBankTernaryButton(TernaryButton normalButton, TernaryButton additionsButton)
|
public readonly BindableWithCurrent<TernaryState> NormalState = new BindableWithCurrent<TernaryState>();
|
||||||
|
public readonly BindableWithCurrent<TernaryState> AdditionsState = new BindableWithCurrent<TernaryState>();
|
||||||
|
|
||||||
|
public DrawableTernaryButton NormalButton { get; private set; } = null!;
|
||||||
|
public DrawableTernaryButton AdditionsButton { get; private set; } = null!;
|
||||||
|
|
||||||
|
public SampleBankTernaryButton(string bankName)
|
||||||
{
|
{
|
||||||
NormalButton = normalButton;
|
BankName = bankName;
|
||||||
AdditionsButton = additionsButton;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -36,7 +45,12 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
|||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Width = 0.5f,
|
Width = 0.5f,
|
||||||
Padding = new MarginPadding { Right = 1 },
|
Padding = new MarginPadding { Right = 1 },
|
||||||
Child = new InlineDrawableTernaryButton(NormalButton),
|
Child = NormalButton = new InlineDrawableTernaryButton
|
||||||
|
{
|
||||||
|
Current = NormalState,
|
||||||
|
Description = BankName.Titleize(),
|
||||||
|
CreateIcon = CreateIcon,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
@ -46,18 +60,18 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
|||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Width = 0.5f,
|
Width = 0.5f,
|
||||||
Padding = new MarginPadding { Left = 1 },
|
Padding = new MarginPadding { Left = 1 },
|
||||||
Child = new InlineDrawableTernaryButton(AdditionsButton),
|
Child = AdditionsButton = new InlineDrawableTernaryButton
|
||||||
|
{
|
||||||
|
Current = AdditionsState,
|
||||||
|
Description = BankName.Titleize(),
|
||||||
|
CreateIcon = CreateIcon,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private partial class InlineDrawableTernaryButton : DrawableTernaryButton
|
private partial class InlineDrawableTernaryButton : DrawableTernaryButton
|
||||||
{
|
{
|
||||||
public InlineDrawableTernaryButton(TernaryButton button)
|
|
||||||
: base(button)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Components.TernaryButtons
|
|
||||||
{
|
|
||||||
public class TernaryButton
|
|
||||||
{
|
|
||||||
public readonly Bindable<TernaryState> Bindable;
|
|
||||||
|
|
||||||
public readonly Bindable<bool> Enabled = new Bindable<bool>(true);
|
|
||||||
|
|
||||||
public readonly string Description;
|
|
||||||
|
|
||||||
/// <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;
|
|
||||||
|
|
||||||
public string Tooltip { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public TernaryButton(Bindable<TernaryState> bindable, string description, Func<Drawable>? createIcon = null)
|
|
||||||
{
|
|
||||||
Bindable = bindable;
|
|
||||||
Description = description;
|
|
||||||
CreateIcon = createIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Toggle()
|
|
||||||
{
|
|
||||||
switch (Bindable.Value)
|
|
||||||
{
|
|
||||||
case TernaryState.False:
|
|
||||||
case TernaryState.Indeterminate:
|
|
||||||
Bindable.Value = TernaryState.True;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TernaryState.True:
|
|
||||||
Bindable.Value = TernaryState.False;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -65,11 +65,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
MainTernaryStates = CreateTernaryButtons().ToArray();
|
MainTernaryStates = CreateTernaryButtons().ToArray();
|
||||||
SampleBankTernaryStates = createSampleBankTernaryButtons(SelectionHandler.SelectionBankStates).ToArray();
|
SampleBankTernaryStates = createSampleBankTernaryButtons().ToArray();
|
||||||
SampleAdditionBankTernaryStates = createSampleBankTernaryButtons(SelectionHandler.SelectionAdditionBankStates).ToArray();
|
|
||||||
|
|
||||||
SelectionHandler.AutoSelectionBankEnabled.BindValueChanged(_ => updateAutoBankTernaryButtonTooltip(), true);
|
|
||||||
SelectionHandler.SelectionAdditionBanksEnabled.BindValueChanged(_ => updateAdditionBankTernaryButtonTooltips(), true);
|
|
||||||
|
|
||||||
AddInternal(new DrawableRulesetDependenciesProvidingContainer(Composer.Ruleset)
|
AddInternal(new DrawableRulesetDependenciesProvidingContainer(Composer.Ruleset)
|
||||||
{
|
{
|
||||||
@ -98,6 +94,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
foreach (var kvp in SelectionHandler.SelectionAdditionBankStates)
|
foreach (var kvp in SelectionHandler.SelectionAdditionBankStates)
|
||||||
kvp.Value.BindValueChanged(_ => updatePlacementSamples());
|
kvp.Value.BindValueChanged(_ => updatePlacementSamples());
|
||||||
|
|
||||||
|
SelectionHandler.AutoSelectionBankEnabled.BindValueChanged(_ => updateAutoBankTernaryButtonTooltip(), true);
|
||||||
|
SelectionHandler.SelectionAdditionBanksEnabled.BindValueChanged(_ => updateAdditionBankTernaryButtonTooltips(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void TransferBlueprintFor(HitObject hitObject, DrawableHitObject drawableObject)
|
protected override void TransferBlueprintFor(HitObject hitObject, DrawableHitObject drawableObject)
|
||||||
@ -238,28 +237,45 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A collection of states which will be displayed to the user in the toolbox.
|
/// A collection of states which will be displayed to the user in the toolbox.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TernaryButton[] MainTernaryStates { get; private set; }
|
public DrawableTernaryButton[] MainTernaryStates { get; private set; }
|
||||||
|
|
||||||
public TernaryButton[] SampleBankTernaryStates { get; private set; }
|
public SampleBankTernaryButton[] SampleBankTernaryStates { get; private set; }
|
||||||
|
|
||||||
public TernaryButton[] SampleAdditionBankTernaryStates { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create all ternary states required to be displayed to the user.
|
/// Create all ternary states required to be displayed to the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual IEnumerable<TernaryButton> CreateTernaryButtons()
|
protected virtual IEnumerable<DrawableTernaryButton> CreateTernaryButtons()
|
||||||
{
|
{
|
||||||
//TODO: this should only be enabled (visible?) for rulesets that provide combo-supporting HitObjects.
|
//TODO: this should only be enabled (visible?) for rulesets that provide combo-supporting HitObjects.
|
||||||
yield return new TernaryButton(NewCombo, "New combo", () => new SpriteIcon { Icon = OsuIcon.EditorNewComboA });
|
yield return new DrawableTernaryButton
|
||||||
|
{
|
||||||
|
Current = NewCombo,
|
||||||
|
Description = "New combo",
|
||||||
|
CreateIcon = () => new SpriteIcon { Icon = OsuIcon.EditorNewComboA },
|
||||||
|
};
|
||||||
|
|
||||||
foreach (var kvp in SelectionHandler.SelectionSampleStates)
|
foreach (var kvp in SelectionHandler.SelectionSampleStates)
|
||||||
yield return new TernaryButton(kvp.Value, kvp.Key.Replace("hit", string.Empty).Titleize(), () => GetIconForSample(kvp.Key));
|
{
|
||||||
|
yield return new DrawableTernaryButton
|
||||||
|
{
|
||||||
|
Current = kvp.Value,
|
||||||
|
Description = kvp.Key.Replace(@"hit", string.Empty).Titleize(),
|
||||||
|
CreateIcon = () => GetIconForSample(kvp.Key),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<TernaryButton> createSampleBankTernaryButtons(Dictionary<string, Bindable<TernaryState>> sampleBankStates)
|
private IEnumerable<SampleBankTernaryButton> createSampleBankTernaryButtons()
|
||||||
{
|
{
|
||||||
foreach (var kvp in sampleBankStates)
|
foreach (string bankName in HitSampleInfo.ALL_BANKS.Prepend(EditorSelectionHandler.HIT_BANK_AUTO))
|
||||||
yield return new TernaryButton(kvp.Value, kvp.Key.Titleize(), () => getIconForBank(kvp.Key));
|
{
|
||||||
|
yield return new SampleBankTernaryButton(bankName)
|
||||||
|
{
|
||||||
|
NormalState = { Current = SelectionHandler.SelectionBankStates[bankName], },
|
||||||
|
AdditionsState = { Current = SelectionHandler.SelectionAdditionBankStates[bankName], },
|
||||||
|
CreateIcon = () => getIconForBank(bankName)
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Drawable getIconForBank(string sampleName)
|
private Drawable getIconForBank(string sampleName)
|
||||||
@ -295,19 +311,19 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
{
|
{
|
||||||
bool enabled = SelectionHandler.AutoSelectionBankEnabled.Value;
|
bool enabled = SelectionHandler.AutoSelectionBankEnabled.Value;
|
||||||
|
|
||||||
var autoBankButton = SampleBankTernaryStates.Single(t => t.Bindable == SelectionHandler.SelectionBankStates[EditorSelectionHandler.HIT_BANK_AUTO]);
|
var autoBankButton = SampleBankTernaryStates.Single(t => t.BankName == EditorSelectionHandler.HIT_BANK_AUTO);
|
||||||
autoBankButton.Enabled.Value = enabled;
|
autoBankButton.NormalButton.Enabled.Value = enabled;
|
||||||
autoBankButton.Tooltip = !enabled ? "Auto normal bank can only be used during hit object placement" : string.Empty;
|
autoBankButton.NormalButton.TooltipText = !enabled ? "Auto normal bank can only be used during hit object placement" : string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAdditionBankTernaryButtonTooltips()
|
private void updateAdditionBankTernaryButtonTooltips()
|
||||||
{
|
{
|
||||||
bool enabled = SelectionHandler.SelectionAdditionBanksEnabled.Value;
|
bool enabled = SelectionHandler.SelectionAdditionBanksEnabled.Value;
|
||||||
|
|
||||||
foreach (var ternaryButton in SampleAdditionBankTernaryStates)
|
foreach (var ternaryButton in SampleBankTernaryStates)
|
||||||
{
|
{
|
||||||
ternaryButton.Enabled.Value = enabled;
|
ternaryButton.AdditionsButton.Enabled.Value = enabled;
|
||||||
ternaryButton.Tooltip = !enabled ? "Add an addition sample first to be able to set a bank" : string.Empty;
|
ternaryButton.AdditionsButton.TooltipText = !enabled ? "Add an addition sample first to be able to set a bank" : string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
|
|
||||||
createStateBindables();
|
createStateBindables();
|
||||||
updateTernaryStates();
|
updateTernaryStates();
|
||||||
togglesCollection.AddRange(createTernaryButtons().Select(b => new DrawableTernaryButton(b) { RelativeSizeAxes = Axes.None, Size = new Vector2(40, 40) }));
|
togglesCollection.AddRange(createTernaryButtons());
|
||||||
}
|
}
|
||||||
|
|
||||||
private string? getCommonBank() => allRelevantSamples.Select(h => GetBankValue(h.samples)).Distinct().Count() == 1
|
private string? getCommonBank() => allRelevantSamples.Select(h => GetBankValue(h.samples)).Distinct().Count() == 1
|
||||||
@ -444,10 +444,19 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<TernaryButton> createTernaryButtons()
|
private IEnumerable<DrawableTernaryButton> createTernaryButtons()
|
||||||
{
|
{
|
||||||
foreach ((string sampleName, var bindable) in selectionSampleStates)
|
foreach ((string sampleName, var bindable) in selectionSampleStates)
|
||||||
yield return new TernaryButton(bindable, string.Empty, () => ComposeBlueprintContainer.GetIconForSample(sampleName));
|
{
|
||||||
|
yield return new DrawableTernaryButton
|
||||||
|
{
|
||||||
|
Current = bindable,
|
||||||
|
Description = string.Empty,
|
||||||
|
CreateIcon = () => ComposeBlueprintContainer.GetIconForSample(sampleName),
|
||||||
|
RelativeSizeAxes = Axes.None,
|
||||||
|
Size = new Vector2(40, 40),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addHitSample(string sampleName)
|
private void addHitSample(string sampleName)
|
||||||
@ -516,7 +525,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
|
|
||||||
if (item is not DrawableTernaryButton button) return base.OnKeyDown(e);
|
if (item is not DrawableTernaryButton button) return base.OnKeyDown(e);
|
||||||
|
|
||||||
button.Button.Toggle();
|
button.Toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -45,6 +45,7 @@ using osu.Game.Rulesets;
|
|||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osu.Game.Screens.Edit.Components.Menus;
|
using osu.Game.Screens.Edit.Components.Menus;
|
||||||
using osu.Game.Screens.Edit.Compose;
|
using osu.Game.Screens.Edit.Compose;
|
||||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||||
@ -54,7 +55,6 @@ using osu.Game.Screens.Edit.Setup;
|
|||||||
using osu.Game.Screens.Edit.Timing;
|
using osu.Game.Screens.Edit.Timing;
|
||||||
using osu.Game.Screens.Edit.Verify;
|
using osu.Game.Screens.Edit.Verify;
|
||||||
using osu.Game.Screens.OnlinePlay;
|
using osu.Game.Screens.OnlinePlay;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
using WebCommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings;
|
using WebCommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings;
|
||||||
@ -63,7 +63,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
{
|
{
|
||||||
[Cached(typeof(IBeatSnapProvider))]
|
[Cached(typeof(IBeatSnapProvider))]
|
||||||
[Cached]
|
[Cached]
|
||||||
public partial class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler<GlobalAction>, IKeyBindingHandler<PlatformAction>, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider
|
public partial class Editor : OsuScreen, IKeyBindingHandler<GlobalAction>, IKeyBindingHandler<PlatformAction>, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An offset applied to waveform visuals to align them with expectations.
|
/// An offset applied to waveform visuals to align them with expectations.
|
||||||
@ -210,6 +210,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
private OnScreenDisplay onScreenDisplay { get; set; }
|
private OnScreenDisplay onScreenDisplay { get; set; }
|
||||||
|
|
||||||
private Bindable<float> editorBackgroundDim;
|
private Bindable<float> editorBackgroundDim;
|
||||||
|
private Bindable<bool> editorShowStoryboard;
|
||||||
private Bindable<bool> editorHitMarkers;
|
private Bindable<bool> editorHitMarkers;
|
||||||
private Bindable<bool> editorAutoSeekOnPlacement;
|
private Bindable<bool> editorAutoSeekOnPlacement;
|
||||||
private Bindable<bool> editorLimitedDistanceSnap;
|
private Bindable<bool> editorLimitedDistanceSnap;
|
||||||
@ -320,6 +321,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
OsuMenuItem redoMenuItem;
|
OsuMenuItem redoMenuItem;
|
||||||
|
|
||||||
editorBackgroundDim = config.GetBindable<float>(OsuSetting.EditorDim);
|
editorBackgroundDim = config.GetBindable<float>(OsuSetting.EditorDim);
|
||||||
|
editorShowStoryboard = config.GetBindable<bool>(OsuSetting.EditorShowStoryboard);
|
||||||
editorHitMarkers = config.GetBindable<bool>(OsuSetting.EditorShowHitMarkers);
|
editorHitMarkers = config.GetBindable<bool>(OsuSetting.EditorShowHitMarkers);
|
||||||
editorAutoSeekOnPlacement = config.GetBindable<bool>(OsuSetting.EditorAutoSeekOnPlacement);
|
editorAutoSeekOnPlacement = config.GetBindable<bool>(OsuSetting.EditorAutoSeekOnPlacement);
|
||||||
editorLimitedDistanceSnap = config.GetBindable<bool>(OsuSetting.EditorLimitedDistanceSnap);
|
editorLimitedDistanceSnap = config.GetBindable<bool>(OsuSetting.EditorLimitedDistanceSnap);
|
||||||
@ -398,7 +400,13 @@ namespace osu.Game.Screens.Edit
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
new OsuMenuItemSpacer(),
|
||||||
new BackgroundDimMenuItem(editorBackgroundDim),
|
new BackgroundDimMenuItem(editorBackgroundDim),
|
||||||
|
new ToggleMenuItem("Show storyboard")
|
||||||
|
{
|
||||||
|
State = { BindTarget = editorShowStoryboard },
|
||||||
|
},
|
||||||
|
new OsuMenuItemSpacer(),
|
||||||
new ToggleMenuItem(EditorStrings.ShowHitMarkers)
|
new ToggleMenuItem(EditorStrings.ShowHitMarkers)
|
||||||
{
|
{
|
||||||
State = { BindTarget = editorHitMarkers },
|
State = { BindTarget = editorHitMarkers },
|
||||||
@ -466,12 +474,14 @@ namespace osu.Game.Screens.Edit
|
|||||||
changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true);
|
changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true);
|
||||||
changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true);
|
changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true);
|
||||||
|
|
||||||
editorBackgroundDim.BindValueChanged(_ => dimBackground());
|
editorBackgroundDim.BindValueChanged(_ => setUpBackground());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private MusicController musicController { get; set; }
|
private MusicController musicController { get; set; }
|
||||||
|
|
||||||
|
protected override BackgroundScreen CreateBackground() => new EditorBackgroundScreen(Beatmap.Value);
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
@ -853,24 +863,23 @@ namespace osu.Game.Screens.Edit
|
|||||||
public override void OnEntering(ScreenTransitionEvent e)
|
public override void OnEntering(ScreenTransitionEvent e)
|
||||||
{
|
{
|
||||||
base.OnEntering(e);
|
base.OnEntering(e);
|
||||||
dimBackground();
|
setUpBackground();
|
||||||
resetTrack(true);
|
resetTrack(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnResuming(ScreenTransitionEvent e)
|
public override void OnResuming(ScreenTransitionEvent e)
|
||||||
{
|
{
|
||||||
base.OnResuming(e);
|
base.OnResuming(e);
|
||||||
dimBackground();
|
setUpBackground();
|
||||||
clock.BindAdjustments();
|
clock.BindAdjustments();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dimBackground()
|
private void setUpBackground()
|
||||||
{
|
{
|
||||||
ApplyToBackground(b =>
|
ApplyToBackground(b =>
|
||||||
{
|
{
|
||||||
b.IgnoreUserSettings.Value = true;
|
var editorBackground = (EditorBackgroundScreen)b;
|
||||||
b.DimWhenUserSettingsIgnored.Value = editorBackgroundDim.Value;
|
editorBackground.ChangeClockSource(clock);
|
||||||
b.BlurAmount.Value = 0;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,11 +918,6 @@ namespace osu.Game.Screens.Edit
|
|||||||
beatmap.EditorTimestamp = clock.CurrentTime;
|
beatmap.EditorTimestamp = clock.CurrentTime;
|
||||||
});
|
});
|
||||||
|
|
||||||
ApplyToBackground(b =>
|
|
||||||
{
|
|
||||||
b.DimWhenUserSettingsIgnored.Value = 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
resetTrack();
|
resetTrack();
|
||||||
|
|
||||||
refetchBeatmap();
|
refetchBeatmap();
|
||||||
|
@ -12,6 +12,7 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Models;
|
using osu.Game.Models;
|
||||||
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Setup
|
namespace osu.Game.Screens.Edit.Setup
|
||||||
@ -87,7 +88,7 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
(metadata, name) => metadata.BackgroundFile = name);
|
(metadata, name) => metadata.BackgroundFile = name);
|
||||||
|
|
||||||
headerBackground.UpdateBackground();
|
headerBackground.UpdateBackground();
|
||||||
editor?.ApplyToBackground(bg => bg.RefreshBackground());
|
editor?.ApplyToBackground(bg => ((EditorBackgroundScreen)bg).RefreshBackground());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,6 +840,7 @@ See the LICENCE file in the repository root for full licence text.
|
|||||||
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=Microsoft_002EToolkit_002EHighPerformance_002EBox_002A/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=Microsoft_002EToolkit_002EHighPerformance_002EBox_002A/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=OpenTabletDriver_002EPlugin_002EDependencyInjection_002E_002A/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=OpenTabletDriver_002EPlugin_002EDependencyInjection_002E_002A/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=Realms_002ELogging_002ELogger/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=Realms_002ELogging_002ELogger/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=Realms_002EThreadSafe_002A/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=System_002EComponentModel_002EComponent/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=System_002EComponentModel_002EComponent/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=System_002EComponentModel_002EContainer/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=System_002EComponentModel_002EContainer/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=System_002ENumerics_002E_002A/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/AutoImport2/=CSHARP/BlackLists/=System_002ENumerics_002E_002A/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
Loading…
Reference in New Issue
Block a user