mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 13:37:25 +08:00
Merge branch 'master' into results-screen-scaling
This commit is contained in:
commit
1677f1d696
@ -55,7 +55,10 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
|
||||
|
||||
AddMoveStep(end_time, 0);
|
||||
AddClickStep(MouseButton.Left);
|
||||
|
||||
AddMoveStep(start_time, 0);
|
||||
AddAssert("duration is positive", () => ((BananaShower)CurrentBlueprint.HitObject).Duration > 0);
|
||||
|
||||
AddClickStep(MouseButton.Right);
|
||||
AddAssert("start time is correct", () => Precision.AlmostEquals(LastObject.HitObject.StartTime, start_time));
|
||||
AddAssert("end time is correct", () => Precision.AlmostEquals(LastObject.HitObject.GetEndTime(), end_time));
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.Input.Events;
|
||||
using osu.Game.Rulesets.Catch.Edit.Blueprints.Components;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
@ -13,11 +14,21 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||
{
|
||||
private readonly TimeSpanOutline outline;
|
||||
|
||||
private double placementStartTime;
|
||||
private double placementEndTime;
|
||||
|
||||
public BananaShowerPlacementBlueprint()
|
||||
{
|
||||
InternalChild = outline = new TimeSpanOutline();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
BeginPlacement();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
@ -38,13 +49,6 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||
case PlacementState.Active:
|
||||
if (e.Button != MouseButton.Right) break;
|
||||
|
||||
// If the duration is negative, swap the start and the end time to make the duration positive.
|
||||
if (HitObject.Duration < 0)
|
||||
{
|
||||
HitObject.StartTime = HitObject.EndTime;
|
||||
HitObject.Duration = -HitObject.Duration;
|
||||
}
|
||||
|
||||
EndPlacement(HitObject.Duration > 0);
|
||||
return true;
|
||||
}
|
||||
@ -61,13 +65,16 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||
switch (PlacementActive)
|
||||
{
|
||||
case PlacementState.Waiting:
|
||||
HitObject.StartTime = time;
|
||||
placementStartTime = placementEndTime = time;
|
||||
break;
|
||||
|
||||
case PlacementState.Active:
|
||||
HitObject.EndTime = time;
|
||||
placementEndTime = time;
|
||||
break;
|
||||
}
|
||||
|
||||
HitObject.StartTime = Math.Min(placementStartTime, placementEndTime);
|
||||
HitObject.EndTime = Math.Max(placementStartTime, placementEndTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||
base.LoadComplete();
|
||||
|
||||
inputManager = GetContainingInputManager();
|
||||
|
||||
BeginPlacement();
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
|
@ -451,6 +451,36 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
AddAssert("mod select hidden", () => modSelectScreen.State.Value == Visibility.Hidden);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestColumnHiding()
|
||||
{
|
||||
AddStep("create screen", () => Child = modSelectScreen = new UserModSelectScreen
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
State = { Value = Visibility.Visible },
|
||||
SelectedMods = { BindTarget = SelectedMods },
|
||||
IsValidMod = mod => mod.Type == ModType.DifficultyIncrease || mod.Type == ModType.Conversion
|
||||
});
|
||||
waitForColumnLoad();
|
||||
changeRuleset(0);
|
||||
|
||||
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
||||
|
||||
AddStep("unset filter", () => modSelectScreen.IsValidMod = _ => true);
|
||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
||||
|
||||
AddStep("filter out everything", () => modSelectScreen.IsValidMod = _ => false);
|
||||
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
||||
|
||||
AddStep("hide", () => modSelectScreen.Hide());
|
||||
AddStep("set filter for 3 columns", () => modSelectScreen.IsValidMod = mod => mod.Type == ModType.DifficultyReduction
|
||||
|| mod.Type == ModType.Automation
|
||||
|| mod.Type == ModType.Conversion);
|
||||
|
||||
AddStep("show", () => modSelectScreen.Show());
|
||||
AddUntilStep("3 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 3);
|
||||
}
|
||||
|
||||
private void waitForColumnLoad() => AddUntilStep("all column content loaded",
|
||||
() => modSelectScreen.ChildrenOfType<ModColumn>().Any() && modSelectScreen.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
|
||||
|
||||
|
@ -153,7 +153,17 @@ namespace osu.Game.Beatmaps
|
||||
}
|
||||
};
|
||||
|
||||
Task.Run(() => cacheDownloadRequest.PerformAsync());
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await cacheDownloadRequest.PerformAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Prevent throwing unobserved exceptions, as they will be logged from the network request to the log file anyway.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private bool checkLocalCache(BeatmapSetInfo set, BeatmapInfo beatmapInfo)
|
||||
|
@ -431,9 +431,10 @@ namespace osu.Game.Beatmaps.Formats
|
||||
OmitFirstBarLine = omitFirstBarSignature,
|
||||
};
|
||||
|
||||
bool isOsuRuleset = beatmap.BeatmapInfo.Ruleset.OnlineID == 0;
|
||||
// scrolling rulesets use effect points rather than difficulty points for scroll speed adjustments.
|
||||
if (!isOsuRuleset)
|
||||
int onlineRulesetID = beatmap.BeatmapInfo.Ruleset.OnlineID;
|
||||
|
||||
// osu!taiko and osu!mania use effect points rather than difficulty points for scroll speed adjustments.
|
||||
if (onlineRulesetID == 1 || onlineRulesetID == 3)
|
||||
effectPoint.ScrollSpeed = speedMultiplier;
|
||||
|
||||
addControlPoint(time, effectPoint, timingChange);
|
||||
|
@ -183,15 +183,15 @@ namespace osu.Game.Beatmaps.Formats
|
||||
SampleControlPoint lastRelevantSamplePoint = null;
|
||||
DifficultyControlPoint lastRelevantDifficultyPoint = null;
|
||||
|
||||
bool isOsuRuleset = onlineRulesetID == 0;
|
||||
// In osu!taiko and osu!mania, a scroll speed is stored as "slider velocity" in legacy formats.
|
||||
// In that case, a scrolling speed change is a global effect and per-hit object difficulty control points are ignored.
|
||||
bool scrollSpeedEncodedAsSliderVelocity = onlineRulesetID == 1 || onlineRulesetID == 3;
|
||||
|
||||
// iterate over hitobjects and pull out all required sample and difficulty changes
|
||||
extractDifficultyControlPoints(beatmap.HitObjects);
|
||||
extractSampleControlPoints(beatmap.HitObjects);
|
||||
|
||||
// handle scroll speed, which is stored as "slider velocity" in legacy formats.
|
||||
// this is relevant for scrolling ruleset beatmaps.
|
||||
if (!isOsuRuleset)
|
||||
if (scrollSpeedEncodedAsSliderVelocity)
|
||||
{
|
||||
foreach (var point in legacyControlPoints.EffectPoints)
|
||||
legacyControlPoints.Add(point.Time, new DifficultyControlPoint { SliderVelocity = point.ScrollSpeed });
|
||||
@ -242,7 +242,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
|
||||
IEnumerable<DifficultyControlPoint> collectDifficultyControlPoints(IEnumerable<HitObject> hitObjects)
|
||||
{
|
||||
if (!isOsuRuleset)
|
||||
if (scrollSpeedEncodedAsSliderVelocity)
|
||||
yield break;
|
||||
|
||||
foreach (var hitObject in hitObjects)
|
||||
|
@ -55,8 +55,18 @@ namespace osu.Game.Overlays.Mods
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this column should accept user input.
|
||||
/// </summary>
|
||||
public Bindable<bool> Active = new BindableBool(true);
|
||||
|
||||
private readonly Bindable<bool> allFiltered = new BindableBool();
|
||||
|
||||
/// <summary>
|
||||
/// True if all of the panels in this column have been filtered out by the current <see cref="Filter"/>.
|
||||
/// </summary>
|
||||
public IBindable<bool> AllFiltered => allFiltered;
|
||||
|
||||
/// <summary>
|
||||
/// List of mods marked as selected in this column.
|
||||
/// </summary>
|
||||
@ -339,6 +349,8 @@ namespace osu.Game.Overlays.Mods
|
||||
panel.ApplyFilter(Filter);
|
||||
}
|
||||
|
||||
allFiltered.Value = panelFlow.All(panel => panel.Filtered.Value);
|
||||
|
||||
if (toggleAllCheckbox != null && !SelectionAnimationRunning)
|
||||
{
|
||||
toggleAllCheckbox.Alpha = panelFlow.Any(panel => !panel.Filtered.Value) ? 1 : 0;
|
||||
|
@ -129,7 +129,6 @@ namespace osu.Game.Overlays.Mods
|
||||
Shear = new Vector2(SHEAR, 0),
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Spacing = new Vector2(10, 0),
|
||||
Margin = new MarginPadding { Horizontal = 70 },
|
||||
Children = new[]
|
||||
{
|
||||
@ -237,12 +236,21 @@ namespace osu.Game.Overlays.Mods
|
||||
}
|
||||
|
||||
private ColumnDimContainer createModColumnContent(ModType modType, Key[]? toggleKeys = null)
|
||||
=> new ColumnDimContainer(CreateModColumn(modType, toggleKeys))
|
||||
{
|
||||
var column = CreateModColumn(modType, toggleKeys).With(column =>
|
||||
{
|
||||
column.Filter = IsValidMod;
|
||||
// spacing applied here rather than via `columnFlow.Spacing` to avoid uneven gaps when some of the columns are hidden.
|
||||
column.Margin = new MarginPadding { Right = 10 };
|
||||
});
|
||||
|
||||
return new ColumnDimContainer(column)
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
RequestScroll = column => columnScroll.ScrollIntoView(column, extraScroll: 140)
|
||||
RequestScroll = col => columnScroll.ScrollIntoView(col, extraScroll: 140),
|
||||
};
|
||||
}
|
||||
|
||||
private ShearedButton[] createDefaultFooterButtons()
|
||||
=> new[]
|
||||
@ -351,6 +359,8 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
#region Transition handling
|
||||
|
||||
private const float distance = 700;
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
const double fade_in_duration = 400;
|
||||
@ -362,13 +372,26 @@ namespace osu.Game.Overlays.Mods
|
||||
.FadeIn(fade_in_duration / 2, Easing.OutQuint)
|
||||
.ScaleTo(1, fade_in_duration, Easing.OutElastic);
|
||||
|
||||
int nonFilteredColumnCount = 0;
|
||||
|
||||
for (int i = 0; i < columnFlow.Count; i++)
|
||||
{
|
||||
columnFlow[i].Column
|
||||
.TopLevelContent
|
||||
.Delay(i * 30)
|
||||
.MoveToY(0, fade_in_duration, Easing.OutQuint)
|
||||
.FadeIn(fade_in_duration, Easing.OutQuint);
|
||||
var column = columnFlow[i].Column;
|
||||
|
||||
double delay = column.AllFiltered.Value ? 0 : nonFilteredColumnCount * 30;
|
||||
double duration = column.AllFiltered.Value ? 0 : fade_in_duration;
|
||||
float startingYPosition = 0;
|
||||
if (!column.AllFiltered.Value)
|
||||
startingYPosition = nonFilteredColumnCount % 2 == 0 ? -distance : distance;
|
||||
|
||||
column.TopLevelContent
|
||||
.MoveToY(startingYPosition)
|
||||
.Delay(delay)
|
||||
.MoveToY(0, duration, Easing.OutQuint)
|
||||
.FadeIn(duration, Easing.OutQuint);
|
||||
|
||||
if (!column.AllFiltered.Value)
|
||||
nonFilteredColumnCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,16 +405,24 @@ namespace osu.Game.Overlays.Mods
|
||||
.FadeOut(fade_out_duration / 2, Easing.OutQuint)
|
||||
.ScaleTo(0.75f, fade_out_duration, Easing.OutQuint);
|
||||
|
||||
int nonFilteredColumnCount = 0;
|
||||
|
||||
for (int i = 0; i < columnFlow.Count; i++)
|
||||
{
|
||||
const float distance = 700;
|
||||
|
||||
var column = columnFlow[i].Column;
|
||||
|
||||
double duration = column.AllFiltered.Value ? 0 : fade_out_duration;
|
||||
float newYPosition = 0;
|
||||
if (!column.AllFiltered.Value)
|
||||
newYPosition = nonFilteredColumnCount % 2 == 0 ? -distance : distance;
|
||||
|
||||
column.FlushPendingSelections();
|
||||
column.TopLevelContent
|
||||
.MoveToY(i % 2 == 0 ? -distance : distance, fade_out_duration, Easing.OutQuint)
|
||||
.FadeOut(fade_out_duration, Easing.OutQuint);
|
||||
.MoveToY(newYPosition, duration, Easing.OutQuint)
|
||||
.FadeOut(duration, Easing.OutQuint);
|
||||
|
||||
if (!column.AllFiltered.Value)
|
||||
nonFilteredColumnCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -557,17 +588,20 @@ namespace osu.Game.Overlays.Mods
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
Active.BindValueChanged(_ => updateDim(), true);
|
||||
Active.BindValueChanged(_ => updateState());
|
||||
Column.AllFiltered.BindValueChanged(_ => updateState(), true);
|
||||
FinishTransforms();
|
||||
}
|
||||
|
||||
protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate || Column.SelectionAnimationRunning;
|
||||
|
||||
private void updateDim()
|
||||
private void updateState()
|
||||
{
|
||||
Colour4 targetColour;
|
||||
|
||||
if (Active.Value)
|
||||
Column.Alpha = Column.AllFiltered.Value ? 0 : 1;
|
||||
|
||||
if (Column.Active.Value)
|
||||
targetColour = Colour4.White;
|
||||
else
|
||||
targetColour = IsHovered ? colours.GrayC : colours.Gray8;
|
||||
@ -586,14 +620,14 @@ namespace osu.Game.Overlays.Mods
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
base.OnHover(e);
|
||||
updateDim();
|
||||
updateState();
|
||||
return Active.Value;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
base.OnHoverLost(e);
|
||||
updateDim();
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Utils
|
||||
|
||||
var options = new SentryOptions
|
||||
{
|
||||
Dsn = "https://5e342cd55f294edebdc9ad604d28bbd3@sentry.io/1255255",
|
||||
Dsn = "https://ad9f78529cef40ac874afb95a9aca04e@sentry.ppy.sh/2",
|
||||
Release = game.Version
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user