mirror of
https://github.com/ppy/osu.git
synced 2025-01-06 07:02:54 +08:00
Merge branch 'master' into lead-in-fixes
This commit is contained in:
commit
5d2a608be0
@ -14,12 +14,13 @@ using osu.Game.Rulesets.Edit;
|
|||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||||
{
|
{
|
||||||
public class PathControlPointPiece : BlueprintPiece<Slider>
|
public class PathControlPointPiece : BlueprintPiece<Slider>
|
||||||
{
|
{
|
||||||
public Action<int> RequestSelection;
|
public Action<int, MouseButtonEvent> RequestSelection;
|
||||||
public Action<Vector2[]> ControlPointsChanged;
|
public Action<Vector2[]> ControlPointsChanged;
|
||||||
|
|
||||||
public readonly BindableBool IsSelected = new BindableBool();
|
public readonly BindableBool IsSelected = new BindableBool();
|
||||||
@ -129,10 +130,19 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
|
|
||||||
protected override bool OnMouseDown(MouseDownEvent e)
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
{
|
{
|
||||||
if (RequestSelection != null)
|
if (RequestSelection == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (e.Button)
|
||||||
{
|
{
|
||||||
RequestSelection.Invoke(Index);
|
case MouseButton.Left:
|
||||||
return true;
|
RequestSelection.Invoke(Index, e);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case MouseButton.Right:
|
||||||
|
if (!IsSelected.Value)
|
||||||
|
RequestSelection.Invoke(Index, e);
|
||||||
|
return false; // Allow context menu to show
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -142,7 +152,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
|
|
||||||
protected override bool OnClick(ClickEvent e) => RequestSelection != null;
|
protected override bool OnClick(ClickEvent e) => RequestSelection != null;
|
||||||
|
|
||||||
protected override bool OnDragStart(DragStartEvent e) => true;
|
protected override bool OnDragStart(DragStartEvent e) => e.Button == MouseButton.Left;
|
||||||
|
|
||||||
protected override bool OnDrag(DragEvent e)
|
protected override bool OnDrag(DragEvent e)
|
||||||
{
|
{
|
||||||
|
@ -3,19 +3,25 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Humanizer;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens.Edit.Compose;
|
using osu.Game.Screens.Edit.Compose;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||||
{
|
{
|
||||||
public class PathControlPointVisualiser : CompositeDrawable, IKeyBindingHandler<PlatformAction>
|
public class PathControlPointVisualiser : CompositeDrawable, IKeyBindingHandler<PlatformAction>, IHasContextMenu
|
||||||
{
|
{
|
||||||
public Action<Vector2[]> ControlPointsChanged;
|
public Action<Vector2[]> ControlPointsChanged;
|
||||||
|
|
||||||
@ -73,9 +79,22 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectPiece(int index)
|
public bool OnPressed(PlatformAction action)
|
||||||
{
|
{
|
||||||
if (inputManager.CurrentState.Keyboard.ControlPressed)
|
switch (action.ActionMethod)
|
||||||
|
{
|
||||||
|
case PlatformActionMethod.Delete:
|
||||||
|
return deleteSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnReleased(PlatformAction action) => action.ActionMethod == PlatformActionMethod.Delete;
|
||||||
|
|
||||||
|
private void selectPiece(int index, MouseButtonEvent e)
|
||||||
|
{
|
||||||
|
if (e.Button == MouseButton.Left && inputManager.CurrentState.Keyboard.ControlPressed)
|
||||||
Pieces[index].IsSelected.Toggle();
|
Pieces[index].IsSelected.Toggle();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -84,50 +103,60 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPressed(PlatformAction action)
|
private bool deleteSelected()
|
||||||
{
|
{
|
||||||
switch (action.ActionMethod)
|
var newControlPoints = new List<Vector2>();
|
||||||
|
|
||||||
|
foreach (var piece in Pieces)
|
||||||
{
|
{
|
||||||
case PlatformActionMethod.Delete:
|
if (!piece.IsSelected.Value)
|
||||||
var newControlPoints = new List<Vector2>();
|
newControlPoints.Add(slider.Path.ControlPoints[piece.Index]);
|
||||||
|
|
||||||
foreach (var piece in Pieces)
|
|
||||||
{
|
|
||||||
if (!piece.IsSelected.Value)
|
|
||||||
newControlPoints.Add(slider.Path.ControlPoints[piece.Index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that there are any points to be deleted
|
|
||||||
if (newControlPoints.Count == slider.Path.ControlPoints.Length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// If there are 0 remaining control points, treat the slider as being deleted
|
|
||||||
if (newControlPoints.Count == 0)
|
|
||||||
{
|
|
||||||
placementHandler?.Delete(slider);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make control points relative
|
|
||||||
Vector2 first = newControlPoints[0];
|
|
||||||
for (int i = 0; i < newControlPoints.Count; i++)
|
|
||||||
newControlPoints[i] = newControlPoints[i] - first;
|
|
||||||
|
|
||||||
// The slider's position defines the position of the first control point, and all further control points are relative to that point
|
|
||||||
slider.Position = slider.Position + first;
|
|
||||||
|
|
||||||
// Since pieces are re-used, they will not point to the deleted control points while remaining selected
|
|
||||||
foreach (var piece in Pieces)
|
|
||||||
piece.IsSelected.Value = false;
|
|
||||||
|
|
||||||
ControlPointsChanged?.Invoke(newControlPoints.ToArray());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
// Ensure that there are any points to be deleted
|
||||||
|
if (newControlPoints.Count == slider.Path.ControlPoints.Length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If there are 0 remaining control points, treat the slider as being deleted
|
||||||
|
if (newControlPoints.Count == 0)
|
||||||
|
{
|
||||||
|
placementHandler?.Delete(slider);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make control points relative
|
||||||
|
Vector2 first = newControlPoints[0];
|
||||||
|
for (int i = 0; i < newControlPoints.Count; i++)
|
||||||
|
newControlPoints[i] = newControlPoints[i] - first;
|
||||||
|
|
||||||
|
// The slider's position defines the position of the first control point, and all further control points are relative to that point
|
||||||
|
slider.Position = slider.Position + first;
|
||||||
|
|
||||||
|
// Since pieces are re-used, they will not point to the deleted control points while remaining selected
|
||||||
|
foreach (var piece in Pieces)
|
||||||
|
piece.IsSelected.Value = false;
|
||||||
|
|
||||||
|
ControlPointsChanged?.Invoke(newControlPoints.ToArray());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnReleased(PlatformAction action) => action.ActionMethod == PlatformActionMethod.Delete;
|
public MenuItem[] ContextMenuItems
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!Pieces.Any(p => p.IsHovered))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int selectedPoints = Pieces.Count(p => p.IsSelected.Value);
|
||||||
|
|
||||||
|
if (selectedPoints == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new MenuItem[]
|
||||||
|
{
|
||||||
|
new OsuMenuItem($"Delete {"control point".ToQuantity(selectedPoints)}", MenuItemType.Destructive, () => deleteSelected())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Framework.Timing;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
@ -18,40 +18,38 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private SkipOverlay skip;
|
private SkipOverlay skip;
|
||||||
private int requestCount;
|
private int requestCount;
|
||||||
|
|
||||||
private FramedOffsetClock offsetClock;
|
|
||||||
private StopwatchClock stopwatchClock;
|
|
||||||
|
|
||||||
private double increment;
|
private double increment;
|
||||||
|
|
||||||
|
private GameplayClockContainer gameplayClockContainer;
|
||||||
|
private GameplayClock gameplayClock;
|
||||||
|
|
||||||
|
private const double skip_time = 6000;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
requestCount = 0;
|
requestCount = 0;
|
||||||
increment = 6000;
|
increment = skip_time;
|
||||||
|
|
||||||
Child = new Container
|
Child = gameplayClockContainer = new GameplayClockContainer(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), new Mod[] { }, 0)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Clock = offsetClock = new FramedOffsetClock(stopwatchClock = new StopwatchClock(true)),
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
skip = new SkipOverlay(6000)
|
skip = new SkipOverlay(skip_time)
|
||||||
{
|
{
|
||||||
RequestSkip = () =>
|
RequestSkip = () =>
|
||||||
{
|
{
|
||||||
requestCount++;
|
requestCount++;
|
||||||
offsetClock.Offset += increment;
|
gameplayClockContainer.Seek(gameplayClock.CurrentTime + increment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
|
||||||
|
|
||||||
protected override void Update()
|
gameplayClockContainer.Start();
|
||||||
{
|
gameplayClock = gameplayClockContainer.GameplayClock;
|
||||||
if (stopwatchClock != null)
|
});
|
||||||
stopwatchClock.Rate = Clock.Rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestFadeOnIdle()
|
public void TestFadeOnIdle()
|
||||||
@ -80,7 +78,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
||||||
AddStep("click", () =>
|
AddStep("click", () =>
|
||||||
{
|
{
|
||||||
increment = 6000 - offsetClock.CurrentTime - GameplayClockContainer.MINIMUM_SKIP_TIME / 2;
|
increment = skip_time - gameplayClock.CurrentTime - GameplayClockContainer.MINIMUM_SKIP_TIME / 2;
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||||
@ -106,7 +104,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
||||||
AddStep("button down", () => InputManager.PressButton(MouseButton.Left));
|
AddStep("button down", () => InputManager.PressButton(MouseButton.Left));
|
||||||
AddUntilStep("wait for overlay disapper", () => !skip.IsAlive);
|
AddUntilStep("wait for overlay disappear", () => !skip.IsPresent);
|
||||||
AddAssert("ensure button didn't disappear", () => skip.Children.First().Alpha > 0);
|
AddAssert("ensure button didn't disappear", () => skip.Children.First().Alpha > 0);
|
||||||
AddStep("button up", () => InputManager.ReleaseButton(MouseButton.Left));
|
AddStep("button up", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
checkRequestCount(0);
|
checkRequestCount(0);
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Overlays.BeatmapSet;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Mania;
|
||||||
|
using osu.Game.Rulesets.Taiko;
|
||||||
|
using osu.Game.Rulesets.Catch;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneLeaderboardModSelector : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(LeaderboardModSelector),
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestSceneLeaderboardModSelector()
|
||||||
|
{
|
||||||
|
LeaderboardModSelector modSelector;
|
||||||
|
FillFlowContainer<SpriteText> selectedMods;
|
||||||
|
var ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
|
Add(selectedMods = new FillFlowContainer<SpriteText>
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(modSelector = new LeaderboardModSelector
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Ruleset = { BindTarget = ruleset }
|
||||||
|
});
|
||||||
|
|
||||||
|
modSelector.SelectedMods.ItemsAdded += mods =>
|
||||||
|
{
|
||||||
|
mods.ForEach(mod => selectedMods.Add(new SpriteText
|
||||||
|
{
|
||||||
|
Text = mod.Acronym,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
modSelector.SelectedMods.ItemsRemoved += mods =>
|
||||||
|
{
|
||||||
|
mods.ForEach(mod =>
|
||||||
|
{
|
||||||
|
foreach (var selected in selectedMods)
|
||||||
|
{
|
||||||
|
if (selected.Text == mod.Acronym)
|
||||||
|
{
|
||||||
|
selectedMods.Remove(selected);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
AddStep("osu ruleset", () => ruleset.Value = new OsuRuleset().RulesetInfo);
|
||||||
|
AddStep("mania ruleset", () => ruleset.Value = new ManiaRuleset().RulesetInfo);
|
||||||
|
AddStep("taiko ruleset", () => ruleset.Value = new TaikoRuleset().RulesetInfo);
|
||||||
|
AddStep("catch ruleset", () => ruleset.Value = new CatchRuleset().RulesetInfo);
|
||||||
|
AddStep("Deselect all", () => modSelector.DeselectAll());
|
||||||
|
AddStep("null ruleset", () => ruleset.Value = null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs
Normal file
23
osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneNewsOverlay : OsuTestScene
|
||||||
|
{
|
||||||
|
private NewsOverlay news;
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
Add(news = new NewsOverlay());
|
||||||
|
AddStep(@"Show", news.Show);
|
||||||
|
AddStep(@"Hide", news.Hide);
|
||||||
|
|
||||||
|
AddStep(@"Show front page", () => news.ShowFrontPage());
|
||||||
|
AddStep(@"Custom article", () => news.Current.Value = "Test Article 101");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
// 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 System.Collections.Generic;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Overlays.Comments;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneTotalCommentsCounter : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(TotalCommentsCounter),
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestSceneTotalCommentsCounter()
|
||||||
|
{
|
||||||
|
var count = new BindableInt();
|
||||||
|
|
||||||
|
Add(new TotalCommentsCounter
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Current = { BindTarget = count }
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep(@"Set 100", () => count.Value = 100);
|
||||||
|
AddStep(@"Set 0", () => count.Value = 0);
|
||||||
|
AddStep(@"Set random", () => count.Value = RNG.Next(0, int.MaxValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
private IReadOnlyList<Type> requiredGameDependencies => new[]
|
private IReadOnlyList<Type> requiredGameDependencies => new[]
|
||||||
{
|
{
|
||||||
typeof(OsuGame),
|
typeof(OsuGame),
|
||||||
typeof(RavenLogger),
|
typeof(SentryLogger),
|
||||||
typeof(OsuLogo),
|
typeof(OsuLogo),
|
||||||
typeof(IdleTracker),
|
typeof(IdleTracker),
|
||||||
typeof(OnScreenDisplay),
|
typeof(OnScreenDisplay),
|
||||||
|
11
osu.Game/Configuration/BackgroundSource.cs
Normal file
11
osu.Game/Configuration/BackgroundSource.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Configuration
|
||||||
|
{
|
||||||
|
public enum BackgroundSource
|
||||||
|
{
|
||||||
|
Skin,
|
||||||
|
Beatmap
|
||||||
|
}
|
||||||
|
}
|
@ -117,6 +117,8 @@ namespace osu.Game.Configuration
|
|||||||
Set(OsuSetting.UIHoldActivationDelay, 200f, 0f, 500f, 50f);
|
Set(OsuSetting.UIHoldActivationDelay, 200f, 0f, 500f, 50f);
|
||||||
|
|
||||||
Set(OsuSetting.IntroSequence, IntroSequence.Triangles);
|
Set(OsuSetting.IntroSequence, IntroSequence.Triangles);
|
||||||
|
|
||||||
|
Set(OsuSetting.MenuBackgroundSource, BackgroundSource.Skin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OsuConfigManager(Storage storage)
|
public OsuConfigManager(Storage storage)
|
||||||
@ -186,6 +188,7 @@ namespace osu.Game.Configuration
|
|||||||
UIScale,
|
UIScale,
|
||||||
IntroSequence,
|
IntroSequence,
|
||||||
UIHoldActivationDelay,
|
UIHoldActivationDelay,
|
||||||
HitLighting
|
HitLighting,
|
||||||
|
MenuBackgroundSource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
osu.Game/Graphics/Backgrounds/BeatmapBackground.cs
Normal file
28
osu.Game/Graphics/Backgrounds/BeatmapBackground.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.Backgrounds
|
||||||
|
{
|
||||||
|
public class BeatmapBackground : Background
|
||||||
|
{
|
||||||
|
public readonly WorkingBeatmap Beatmap;
|
||||||
|
|
||||||
|
private readonly string fallbackTextureName;
|
||||||
|
|
||||||
|
public BeatmapBackground(WorkingBeatmap beatmap, string fallbackTextureName = @"Backgrounds/bg1")
|
||||||
|
{
|
||||||
|
Beatmap = beatmap;
|
||||||
|
this.fallbackTextureName = fallbackTextureName;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
Sprite.Texture = Beatmap?.Background ?? textures.Get(fallbackTextureName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -71,7 +71,7 @@ namespace osu.Game
|
|||||||
[Cached]
|
[Cached]
|
||||||
private readonly ScreenshotManager screenshotManager = new ScreenshotManager();
|
private readonly ScreenshotManager screenshotManager = new ScreenshotManager();
|
||||||
|
|
||||||
protected RavenLogger RavenLogger;
|
protected SentryLogger SentryLogger;
|
||||||
|
|
||||||
public virtual Storage GetStorageForStableInstall() => null;
|
public virtual Storage GetStorageForStableInstall() => null;
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
forwardLoggedErrorsToNotifications();
|
forwardLoggedErrorsToNotifications();
|
||||||
|
|
||||||
RavenLogger = new RavenLogger(this);
|
SentryLogger = new SentryLogger(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBlockingOverlayFade() =>
|
private void updateBlockingOverlayFade() =>
|
||||||
@ -166,7 +166,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
dependencies.CacheAs(this);
|
dependencies.CacheAs(this);
|
||||||
|
|
||||||
dependencies.Cache(RavenLogger);
|
dependencies.Cache(SentryLogger);
|
||||||
|
|
||||||
dependencies.Cache(osuLogo = new OsuLogo { Alpha = 0 });
|
dependencies.Cache(osuLogo = new OsuLogo { Alpha = 0 });
|
||||||
|
|
||||||
@ -486,7 +486,7 @@ namespace osu.Game
|
|||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
RavenLogger.Dispose();
|
SentryLogger.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
144
osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs
Normal file
144
osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osuTK;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.BeatmapSet
|
||||||
|
{
|
||||||
|
public class LeaderboardModSelector : CompositeDrawable
|
||||||
|
{
|
||||||
|
public readonly BindableList<Mod> SelectedMods = new BindableList<Mod>();
|
||||||
|
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
|
private readonly FillFlowContainer<ModButton> modsContainer;
|
||||||
|
|
||||||
|
public LeaderboardModSelector()
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
InternalChild = modsContainer = new FillFlowContainer<ModButton>
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Full,
|
||||||
|
Spacing = new Vector2(4),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
Ruleset.BindValueChanged(onRulesetChanged, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRulesetChanged(ValueChangedEvent<RulesetInfo> ruleset)
|
||||||
|
{
|
||||||
|
SelectedMods.Clear();
|
||||||
|
modsContainer.Clear();
|
||||||
|
|
||||||
|
if (ruleset.NewValue == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
modsContainer.Add(new ModButton(new ModNoMod()));
|
||||||
|
modsContainer.AddRange(ruleset.NewValue.CreateInstance().GetAllMods().Where(m => m.Ranked).Select(m => new ModButton(m)));
|
||||||
|
|
||||||
|
modsContainer.ForEach(button => button.OnSelectionChanged = selectionChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(HoverEvent e)
|
||||||
|
{
|
||||||
|
updateHighlighted();
|
||||||
|
return base.OnHover(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
|
{
|
||||||
|
base.OnHoverLost(e);
|
||||||
|
updateHighlighted();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectionChanged(Mod mod, bool selected)
|
||||||
|
{
|
||||||
|
if (selected)
|
||||||
|
SelectedMods.Add(mod);
|
||||||
|
else
|
||||||
|
SelectedMods.Remove(mod);
|
||||||
|
|
||||||
|
updateHighlighted();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHighlighted()
|
||||||
|
{
|
||||||
|
if (SelectedMods.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
modsContainer.Children.Where(button => !button.IsHovered).ForEach(button => button.Highlighted.Value = !IsHovered);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeselectAll() => modsContainer.ForEach(mod => mod.Selected.Value = false);
|
||||||
|
|
||||||
|
private class ModButton : ModIcon
|
||||||
|
{
|
||||||
|
private const int duration = 200;
|
||||||
|
|
||||||
|
public readonly BindableBool Highlighted = new BindableBool();
|
||||||
|
public Action<Mod, bool> OnSelectionChanged;
|
||||||
|
|
||||||
|
public ModButton(Mod mod)
|
||||||
|
: base(mod)
|
||||||
|
{
|
||||||
|
Scale = new Vector2(0.4f);
|
||||||
|
Add(new HoverClickSounds());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Highlighted.BindValueChanged(highlighted =>
|
||||||
|
{
|
||||||
|
if (Selected.Value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.FadeColour(highlighted.NewValue ? Color4.White : Color4.DimGray, duration, Easing.OutQuint);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
Selected.BindValueChanged(selected =>
|
||||||
|
{
|
||||||
|
OnSelectionChanged?.Invoke(Mod, selected.NewValue);
|
||||||
|
Highlighted.TriggerChange();
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnClick(ClickEvent e)
|
||||||
|
{
|
||||||
|
Selected.Toggle();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(HoverEvent e)
|
||||||
|
{
|
||||||
|
Highlighted.Value = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
|
{
|
||||||
|
base.OnHoverLost(e);
|
||||||
|
Highlighted.Value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
osu.Game/Overlays/Comments/TotalCommentsCounter.cs
Normal file
80
osu.Game/Overlays/Comments/TotalCommentsCounter.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osuTK;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Comments
|
||||||
|
{
|
||||||
|
public class TotalCommentsCounter : CompositeDrawable
|
||||||
|
{
|
||||||
|
public readonly BindableInt Current = new BindableInt();
|
||||||
|
|
||||||
|
private readonly SpriteText counter;
|
||||||
|
|
||||||
|
public TotalCommentsCounter()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
Height = 50;
|
||||||
|
AddInternal(new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Margin = new MarginPadding { Left = 50 },
|
||||||
|
Spacing = new Vector2(5, 0),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new SpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Font = OsuFont.GetFont(size: 20, italics: true),
|
||||||
|
Text = @"Comments"
|
||||||
|
},
|
||||||
|
new CircularContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Masking = true,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.Gray(0.05f)
|
||||||
|
},
|
||||||
|
counter = new SpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Margin = new MarginPadding { Horizontal = 10, Vertical = 5 },
|
||||||
|
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
counter.Colour = colours.BlueLighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
Current.BindValueChanged(value => counter.Text = value.NewValue.ToString("N0"), true);
|
||||||
|
base.LoadComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -241,7 +241,7 @@ namespace osu.Game.Overlays.Dialog
|
|||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
if (!actionInvoked)
|
if (!actionInvoked && content.IsPresent)
|
||||||
// In the case a user did not choose an action before a hide was triggered, press the last button.
|
// In the case a user did not choose an action before a hide was triggered, press the last button.
|
||||||
// This is presumed to always be a sane default "cancel" action.
|
// This is presumed to always be a sane default "cancel" action.
|
||||||
buttonsContainer.Last().Click();
|
buttonsContainer.Last().Click();
|
||||||
|
@ -96,7 +96,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foregroundIcon.Highlighted.Value = Selected;
|
foregroundIcon.Selected.Value = Selected;
|
||||||
|
|
||||||
SelectionChanged?.Invoke(SelectedMod);
|
SelectionChanged?.Invoke(SelectedMod);
|
||||||
return true;
|
return true;
|
||||||
|
19
osu.Game/Overlays/News/NewsContent.cs
Normal file
19
osu.Game/Overlays/News/NewsContent.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.News
|
||||||
|
{
|
||||||
|
public abstract class NewsContent : FillFlowContainer
|
||||||
|
{
|
||||||
|
protected NewsContent()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
Direction = FillDirection.Vertical;
|
||||||
|
Padding = new MarginPadding { Bottom = 100, Top = 20, Horizontal = 50 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
109
osu.Game/Overlays/News/NewsHeader.cs
Normal file
109
osu.Game/Overlays/News/NewsHeader.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.News
|
||||||
|
{
|
||||||
|
public class NewsHeader : OverlayHeader
|
||||||
|
{
|
||||||
|
private const string front_page_string = "Front Page";
|
||||||
|
|
||||||
|
private NewsHeaderTitle title;
|
||||||
|
|
||||||
|
public readonly Bindable<string> Current = new Bindable<string>(null);
|
||||||
|
|
||||||
|
public Action ShowFrontPage;
|
||||||
|
|
||||||
|
public NewsHeader()
|
||||||
|
{
|
||||||
|
TabControl.AddItem(front_page_string);
|
||||||
|
|
||||||
|
TabControl.Current.ValueChanged += e =>
|
||||||
|
{
|
||||||
|
if (e.NewValue == front_page_string)
|
||||||
|
ShowFrontPage?.Invoke();
|
||||||
|
};
|
||||||
|
|
||||||
|
Current.ValueChanged += showArticle;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colour)
|
||||||
|
{
|
||||||
|
TabControl.AccentColour = colour.Violet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showArticle(ValueChangedEvent<string> e)
|
||||||
|
{
|
||||||
|
if (e.OldValue != null)
|
||||||
|
TabControl.RemoveItem(e.OldValue);
|
||||||
|
|
||||||
|
if (e.NewValue != null)
|
||||||
|
{
|
||||||
|
TabControl.AddItem(e.NewValue);
|
||||||
|
TabControl.Current.Value = e.NewValue;
|
||||||
|
|
||||||
|
title.IsReadingArticle = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TabControl.Current.Value = front_page_string;
|
||||||
|
title.IsReadingArticle = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Drawable CreateBackground() => new NewsHeaderBackground();
|
||||||
|
|
||||||
|
protected override Drawable CreateContent() => new Container();
|
||||||
|
|
||||||
|
protected override ScreenTitle CreateTitle() => title = new NewsHeaderTitle();
|
||||||
|
|
||||||
|
private class NewsHeaderBackground : Sprite
|
||||||
|
{
|
||||||
|
public NewsHeaderBackground()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
FillMode = FillMode.Fill;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
Texture = textures.Get(@"Headers/news");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NewsHeaderTitle : ScreenTitle
|
||||||
|
{
|
||||||
|
private const string article_string = "Article";
|
||||||
|
|
||||||
|
public bool IsReadingArticle
|
||||||
|
{
|
||||||
|
set => Section = value ? article_string : front_page_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NewsHeaderTitle()
|
||||||
|
{
|
||||||
|
Title = "News";
|
||||||
|
IsReadingArticle = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/news");
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
AccentColour = colours.Violet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
68
osu.Game/Overlays/NewsOverlay.cs
Normal file
68
osu.Game/Overlays/NewsOverlay.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Overlays.News;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays
|
||||||
|
{
|
||||||
|
public class NewsOverlay : FullscreenOverlay
|
||||||
|
{
|
||||||
|
private NewsHeader header;
|
||||||
|
|
||||||
|
//ReSharper disable NotAccessedField.Local
|
||||||
|
private Container<NewsContent> content;
|
||||||
|
|
||||||
|
public readonly Bindable<string> Current = new Bindable<string>(null);
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = colours.PurpleDarkAlternative
|
||||||
|
},
|
||||||
|
new OsuScrollContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
header = new NewsHeader
|
||||||
|
{
|
||||||
|
ShowFrontPage = ShowFrontPage
|
||||||
|
},
|
||||||
|
content = new Container<NewsContent>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
header.Current.BindTo(Current);
|
||||||
|
Current.TriggerChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowFrontPage()
|
||||||
|
{
|
||||||
|
Current.Value = null;
|
||||||
|
Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -60,7 +60,10 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
dropdown = new AudioDeviceSettingsDropdown()
|
dropdown = new AudioDeviceSettingsDropdown
|
||||||
|
{
|
||||||
|
Keywords = new[] { "speaker", "headphone", "output" }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
updateItems();
|
updateItems();
|
||||||
|
@ -34,6 +34,12 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
|
|||||||
Bindable = config.GetBindable<IntroSequence>(OsuSetting.IntroSequence),
|
Bindable = config.GetBindable<IntroSequence>(OsuSetting.IntroSequence),
|
||||||
Items = Enum.GetValues(typeof(IntroSequence)).Cast<IntroSequence>()
|
Items = Enum.GetValues(typeof(IntroSequence)).Cast<IntroSequence>()
|
||||||
},
|
},
|
||||||
|
new SettingsDropdown<BackgroundSource>
|
||||||
|
{
|
||||||
|
LabelText = "Background source",
|
||||||
|
Bindable = config.GetBindable<BackgroundSource>(OsuSetting.MenuBackgroundSource),
|
||||||
|
Items = Enum.GetValues(typeof(BackgroundSource)).Cast<BackgroundSource>()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Overlays.Settings.Sections.Audio;
|
using osu.Game.Overlays.Settings.Sections.Audio;
|
||||||
@ -10,6 +12,9 @@ namespace osu.Game.Overlays.Settings.Sections
|
|||||||
public class AudioSection : SettingsSection
|
public class AudioSection : SettingsSection
|
||||||
{
|
{
|
||||||
public override string Header => "Audio";
|
public override string Header => "Audio";
|
||||||
|
|
||||||
|
public override IEnumerable<string> FilterTerms => base.FilterTerms.Concat(new[] { "sound" });
|
||||||
|
|
||||||
public override IconUsage Icon => FontAwesome.Solid.VolumeUp;
|
public override IconUsage Icon => FontAwesome.Solid.VolumeUp;
|
||||||
|
|
||||||
public AudioSection()
|
public AudioSection()
|
||||||
|
@ -38,6 +38,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
{
|
{
|
||||||
LabelText = "Show health display even when you can't fail",
|
LabelText = "Show health display even when you can't fail",
|
||||||
Bindable = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail),
|
Bindable = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail),
|
||||||
|
Keywords = new[] { "hp", "bar" }
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
|
@ -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 System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
|
||||||
@ -10,6 +12,8 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
{
|
{
|
||||||
protected override string Header => "Mods";
|
protected override string Header => "Mods";
|
||||||
|
|
||||||
|
public override IEnumerable<string> FilterTerms => base.FilterTerms.Concat(new[] { "mod" });
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
@ -18,7 +22,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Increase visibility of first object when visual impairment mods are enabled",
|
LabelText = "Increase visibility of first object when visual impairment mods are enabled",
|
||||||
Bindable = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility)
|
Bindable = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -31,13 +31,15 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
{
|
{
|
||||||
LabelText = "Display beatmaps from",
|
LabelText = "Display beatmaps from",
|
||||||
Bindable = config.GetBindable<double>(OsuSetting.DisplayStarsMinimum),
|
Bindable = config.GetBindable<double>(OsuSetting.DisplayStarsMinimum),
|
||||||
KeyboardStep = 0.1f
|
KeyboardStep = 0.1f,
|
||||||
|
Keywords = new[] { "star", "difficulty" }
|
||||||
},
|
},
|
||||||
new SettingsSlider<double, StarSlider>
|
new SettingsSlider<double, StarSlider>
|
||||||
{
|
{
|
||||||
LabelText = "up to",
|
LabelText = "up to",
|
||||||
Bindable = config.GetBindable<double>(OsuSetting.DisplayStarsMaximum),
|
Bindable = config.GetBindable<double>(OsuSetting.DisplayStarsMaximum),
|
||||||
KeyboardStep = 0.1f
|
KeyboardStep = 0.1f,
|
||||||
|
Keywords = new[] { "star", "difficulty" }
|
||||||
},
|
},
|
||||||
new SettingsEnumDropdown<RandomSelectAlgorithm>
|
new SettingsEnumDropdown<RandomSelectAlgorithm>
|
||||||
{
|
{
|
||||||
|
@ -75,12 +75,14 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
LabelText = "UI Scaling",
|
LabelText = "UI Scaling",
|
||||||
TransferValueOnCommit = true,
|
TransferValueOnCommit = true,
|
||||||
Bindable = osuConfig.GetBindable<float>(OsuSetting.UIScale),
|
Bindable = osuConfig.GetBindable<float>(OsuSetting.UIScale),
|
||||||
KeyboardStep = 0.01f
|
KeyboardStep = 0.01f,
|
||||||
|
Keywords = new[] { "scale", "letterbox" },
|
||||||
},
|
},
|
||||||
new SettingsEnumDropdown<ScalingMode>
|
new SettingsEnumDropdown<ScalingMode>
|
||||||
{
|
{
|
||||||
LabelText = "Screen Scaling",
|
LabelText = "Screen Scaling",
|
||||||
Bindable = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling),
|
Bindable = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling),
|
||||||
|
Keywords = new[] { "scale", "letterbox" },
|
||||||
},
|
},
|
||||||
scalingSettings = new FillFlowContainer<SettingsSlider<float>>
|
scalingSettings = new FillFlowContainer<SettingsSlider<float>>
|
||||||
{
|
{
|
||||||
|
@ -76,7 +76,9 @@ namespace osu.Game.Overlays.Settings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IEnumerable<string> FilterTerms => new[] { LabelText };
|
public virtual IEnumerable<string> FilterTerms => Keywords == null ? new[] { LabelText } : new List<string>(Keywords) { LabelText }.ToArray();
|
||||||
|
|
||||||
|
public IEnumerable<string> Keywords { get; set; }
|
||||||
|
|
||||||
public bool MatchingFilter
|
public bool MatchingFilter
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
public abstract string Header { get; }
|
public abstract string Header { get; }
|
||||||
|
|
||||||
public IEnumerable<IFilterable> FilterableChildren => Children.OfType<IFilterable>();
|
public IEnumerable<IFilterable> FilterableChildren => Children.OfType<IFilterable>();
|
||||||
public IEnumerable<string> FilterTerms => new[] { Header };
|
public virtual IEnumerable<string> FilterTerms => new[] { Header };
|
||||||
|
|
||||||
private const int header_size = 26;
|
private const int header_size = 26;
|
||||||
private const int header_margin = 25;
|
private const int header_margin = 25;
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
protected abstract string Header { get; }
|
protected abstract string Header { get; }
|
||||||
|
|
||||||
public IEnumerable<IFilterable> FilterableChildren => Children.OfType<IFilterable>();
|
public IEnumerable<IFilterable> FilterableChildren => Children.OfType<IFilterable>();
|
||||||
public IEnumerable<string> FilterTerms => new[] { Header };
|
public virtual IEnumerable<string> FilterTerms => new[] { Header };
|
||||||
|
|
||||||
public bool MatchingFilter
|
public bool MatchingFilter
|
||||||
{
|
{
|
||||||
|
@ -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.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -11,5 +13,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Name => "No Mod";
|
public override string Name => "No Mod";
|
||||||
public override string Acronym => "NM";
|
public override string Acronym => "NM";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
public override IconUsage Icon => FontAwesome.Solid.Ban;
|
||||||
|
public override ModType Type => ModType.System;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
public class ModIcon : Container, IHasTooltip
|
public class ModIcon : Container, IHasTooltip
|
||||||
{
|
{
|
||||||
public readonly BindableBool Highlighted = new BindableBool();
|
public readonly BindableBool Selected = new BindableBool();
|
||||||
|
|
||||||
private readonly SpriteIcon modIcon;
|
private readonly SpriteIcon modIcon;
|
||||||
private readonly SpriteIcon background;
|
private readonly SpriteIcon background;
|
||||||
@ -34,9 +34,11 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
public virtual string TooltipText { get; }
|
public virtual string TooltipText { get; }
|
||||||
|
|
||||||
|
protected Mod Mod { get; private set; }
|
||||||
|
|
||||||
public ModIcon(Mod mod)
|
public ModIcon(Mod mod)
|
||||||
{
|
{
|
||||||
if (mod == null) throw new ArgumentNullException(nameof(mod));
|
Mod = mod ?? throw new ArgumentNullException(nameof(mod));
|
||||||
|
|
||||||
type = mod.Type;
|
type = mod.Type;
|
||||||
|
|
||||||
@ -98,13 +100,19 @@ namespace osu.Game.Rulesets.UI
|
|||||||
backgroundColour = colours.Pink;
|
backgroundColour = colours.Pink;
|
||||||
highlightedColour = colours.PinkLight;
|
highlightedColour = colours.PinkLight;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ModType.System:
|
||||||
|
backgroundColour = colours.Gray6;
|
||||||
|
highlightedColour = colours.Gray7;
|
||||||
|
modIcon.Colour = colours.Yellow;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
Highlighted.BindValueChanged(highlighted => background.Colour = highlighted.NewValue ? highlightedColour : backgroundColour, true);
|
Selected.BindValueChanged(selected => background.Colour = selected.NewValue ? highlightedColour : backgroundColour, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ using System.Threading;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Textures;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
@ -107,22 +106,6 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
return base.Equals(other) && beatmap == otherBeatmapBackground.Beatmap;
|
return base.Equals(other) && beatmap == otherBeatmapBackground.Beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class BeatmapBackground : Background
|
|
||||||
{
|
|
||||||
public readonly WorkingBeatmap Beatmap;
|
|
||||||
|
|
||||||
public BeatmapBackground(WorkingBeatmap beatmap)
|
|
||||||
{
|
|
||||||
Beatmap = beatmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(TextureStore textures)
|
|
||||||
{
|
|
||||||
Sprite.Texture = Beatmap?.Background ?? textures.Get(@"Backgrounds/bg1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DimmableBackground : UserDimContainer
|
public class DimmableBackground : UserDimContainer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -6,6 +6,8 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
@ -24,6 +26,10 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
|
|
||||||
private Bindable<User> user;
|
private Bindable<User> user;
|
||||||
private Bindable<Skin> skin;
|
private Bindable<Skin> skin;
|
||||||
|
private Bindable<BackgroundSource> mode;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<WorkingBeatmap> beatmap { get; set; }
|
||||||
|
|
||||||
public BackgroundScreenDefault(bool animateOnEnter = true)
|
public BackgroundScreenDefault(bool animateOnEnter = true)
|
||||||
: base(animateOnEnter)
|
: base(animateOnEnter)
|
||||||
@ -31,13 +37,16 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(IAPIProvider api, SkinManager skinManager)
|
private void load(IAPIProvider api, SkinManager skinManager, OsuConfigManager config)
|
||||||
{
|
{
|
||||||
user = api.LocalUser.GetBoundCopy();
|
user = api.LocalUser.GetBoundCopy();
|
||||||
skin = skinManager.CurrentSkin.GetBoundCopy();
|
skin = skinManager.CurrentSkin.GetBoundCopy();
|
||||||
|
mode = config.GetBindable<BackgroundSource>(OsuSetting.MenuBackgroundSource);
|
||||||
|
|
||||||
user.ValueChanged += _ => Next();
|
user.ValueChanged += _ => Next();
|
||||||
skin.ValueChanged += _ => Next();
|
skin.ValueChanged += _ => Next();
|
||||||
|
mode.ValueChanged += _ => Next();
|
||||||
|
beatmap.ValueChanged += _ => Next();
|
||||||
|
|
||||||
currentDisplay = RNG.Next(0, background_count);
|
currentDisplay = RNG.Next(0, background_count);
|
||||||
|
|
||||||
@ -66,7 +75,18 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
Background newBackground;
|
Background newBackground;
|
||||||
|
|
||||||
if (user.Value?.IsSupporter ?? false)
|
if (user.Value?.IsSupporter ?? false)
|
||||||
newBackground = new SkinnedBackground(skin.Value, backgroundName);
|
{
|
||||||
|
switch (mode.Value)
|
||||||
|
{
|
||||||
|
case BackgroundSource.Beatmap:
|
||||||
|
newBackground = new BeatmapBackground(beatmap.Value, backgroundName);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
newBackground = new SkinnedBackground(skin.Value, backgroundName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
newBackground = new Background(backgroundName);
|
newBackground = new Background(backgroundName);
|
||||||
|
|
||||||
|
@ -313,14 +313,15 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
/// Attempts to select any hovered blueprints.
|
/// Attempts to select any hovered blueprints.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="e">The input event that triggered this selection.</param>
|
/// <param name="e">The input event that triggered this selection.</param>
|
||||||
private void beginClickSelection(UIEvent e)
|
private void beginClickSelection(MouseButtonEvent e)
|
||||||
{
|
{
|
||||||
Debug.Assert(!clickSelectionBegan);
|
Debug.Assert(!clickSelectionBegan);
|
||||||
|
|
||||||
// If a select blueprint is already hovered, disallow changes in selection.
|
// Deselections are only allowed for control + left clicks
|
||||||
// Exception is made when holding control, as deselection should still be allowed.
|
bool allowDeselection = e.ControlPressed && e.Button == MouseButton.Left;
|
||||||
if (!e.CurrentState.Keyboard.ControlPressed &&
|
|
||||||
selectionHandler.SelectedBlueprints.Any(s => s.IsHovered))
|
// Todo: This is probably incorrectly disallowing multiple selections on stacked objects
|
||||||
|
if (!allowDeselection && selectionHandler.SelectedBlueprints.Any(s => s.IsHovered))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (SelectionBlueprint blueprint in selectionBlueprints.AliveBlueprints)
|
foreach (SelectionBlueprint blueprint in selectionBlueprints.AliveBlueprints)
|
||||||
|
@ -10,7 +10,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -170,8 +169,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
track.Start();
|
track.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Beatmap.ValueChanged += beatmap_ValueChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool exitConfirmed;
|
private bool exitConfirmed;
|
||||||
@ -220,14 +217,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
seq.OnAbort(_ => buttons.SetOsuLogo(null));
|
seq.OnAbort(_ => buttons.SetOsuLogo(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beatmap_ValueChanged(ValueChangedEvent<WorkingBeatmap> e)
|
|
||||||
{
|
|
||||||
if (!this.IsCurrentScreen())
|
|
||||||
return;
|
|
||||||
|
|
||||||
((BackgroundScreenDefault)Background).Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnSuspending(IScreen next)
|
public override void OnSuspending(IScreen next)
|
||||||
{
|
{
|
||||||
base.OnSuspending(next);
|
base.OnSuspending(next);
|
||||||
|
@ -19,6 +19,7 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
@ -35,6 +36,9 @@ namespace osu.Game.Screens.Play
|
|||||||
private FadeContainer fadeContainer;
|
private FadeContainer fadeContainer;
|
||||||
private double displayTime;
|
private double displayTime;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private GameplayClock gameplayClock { get; set; }
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -45,8 +49,6 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
this.startTime = startTime;
|
this.startTime = startTime;
|
||||||
|
|
||||||
Show();
|
|
||||||
|
|
||||||
RelativePositionAxes = Axes.Both;
|
RelativePositionAxes = Axes.Both;
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
|
||||||
@ -57,13 +59,8 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuColour colours, GameplayClock clock)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
var baseClock = Clock;
|
|
||||||
|
|
||||||
if (clock != null)
|
|
||||||
Clock = clock;
|
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
fadeContainer = new FadeContainer
|
fadeContainer = new FadeContainer
|
||||||
@ -73,7 +70,6 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
button = new Button
|
button = new Button
|
||||||
{
|
{
|
||||||
Clock = baseClock,
|
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
},
|
},
|
||||||
@ -92,40 +88,40 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
private const double fade_time = 300;
|
private const double fade_time = 300;
|
||||||
|
|
||||||
private double beginFadeTime => startTime - fade_time;
|
private double fadeOutBeginTime => startTime - GameplayClockContainer.MINIMUM_SKIP_TIME;
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
// skip is not required if there is no extra "empty" time to skip.
|
// skip is not required if there is no extra "empty" time to skip.
|
||||||
if (Clock.CurrentTime > beginFadeTime - GameplayClockContainer.MINIMUM_SKIP_TIME)
|
// we may need to remove this if rewinding before the initial player load position becomes a thing.
|
||||||
|
if (fadeOutBeginTime < gameplayClock.CurrentTime)
|
||||||
{
|
{
|
||||||
Alpha = 0;
|
|
||||||
Expire();
|
Expire();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.FadeInFromZero(fade_time);
|
|
||||||
using (BeginAbsoluteSequence(beginFadeTime))
|
|
||||||
this.FadeOut(fade_time);
|
|
||||||
|
|
||||||
button.Action = () => RequestSkip?.Invoke();
|
button.Action = () => RequestSkip?.Invoke();
|
||||||
|
displayTime = gameplayClock.CurrentTime;
|
||||||
|
|
||||||
displayTime = Time.Current;
|
Show();
|
||||||
Expire();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopIn() => this.FadeIn();
|
protected override void PopIn() => this.FadeIn(fade_time);
|
||||||
|
|
||||||
protected override void PopOut() => this.FadeOut();
|
protected override void PopOut() => this.FadeOut(fade_time);
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
remainingTimeBox.ResizeWidthTo((float)Math.Max(0, 1 - (Time.Current - displayTime) / (beginFadeTime - displayTime)), 120, Easing.OutQuint);
|
|
||||||
|
|
||||||
button.Enabled.Value = Time.Current < startTime - GameplayClockContainer.MINIMUM_SKIP_TIME;
|
var progress = Math.Max(0, 1 - (gameplayClock.CurrentTime - displayTime) / (fadeOutBeginTime - displayTime));
|
||||||
|
|
||||||
|
remainingTimeBox.Width = (float)Interpolation.Lerp(remainingTimeBox.Width, progress, Math.Clamp(Time.Elapsed / 40, 0, 1));
|
||||||
|
|
||||||
|
button.Enabled.Value = progress > 0;
|
||||||
|
State.Value = progress > 0 ? Visibility.Visible : Visibility.Hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||||
|
@ -640,10 +640,19 @@ namespace osu.Game.Screens.Select
|
|||||||
itemsCache.Validate();
|
itemsCache.Validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool firstScroll = true;
|
||||||
|
|
||||||
private void updateScrollPosition()
|
private void updateScrollPosition()
|
||||||
{
|
{
|
||||||
if (scrollTarget != null)
|
if (scrollTarget != null)
|
||||||
{
|
{
|
||||||
|
if (firstScroll)
|
||||||
|
{
|
||||||
|
// reduce movement when first displaying the carousel.
|
||||||
|
scroll.ScrollTo(scrollTarget.Value - 200, false);
|
||||||
|
firstScroll = false;
|
||||||
|
}
|
||||||
|
|
||||||
scroll.ScrollTo(scrollTarget.Value);
|
scroll.ScrollTo(scrollTarget.Value);
|
||||||
scrollPositionCache.Validate();
|
scrollPositionCache.Validate();
|
||||||
}
|
}
|
||||||
|
@ -2,31 +2,34 @@
|
|||||||
// 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 System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using SharpRaven;
|
using Sentry;
|
||||||
using SharpRaven.Data;
|
|
||||||
|
|
||||||
namespace osu.Game.Utils
|
namespace osu.Game.Utils
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Report errors to sentry.
|
/// Report errors to sentry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RavenLogger : IDisposable
|
public class SentryLogger : IDisposable
|
||||||
{
|
{
|
||||||
private readonly RavenClient raven = new RavenClient("https://5e342cd55f294edebdc9ad604d28bbd3@sentry.io/1255255");
|
private SentryClient sentry;
|
||||||
|
private Scope sentryScope;
|
||||||
|
|
||||||
private readonly List<Task> tasks = new List<Task>();
|
public SentryLogger(OsuGame game)
|
||||||
|
|
||||||
public RavenLogger(OsuGame game)
|
|
||||||
{
|
{
|
||||||
raven.Release = game.Version;
|
|
||||||
|
|
||||||
if (!game.IsDeployedBuild) return;
|
if (!game.IsDeployedBuild) return;
|
||||||
|
|
||||||
|
var options = new SentryOptions
|
||||||
|
{
|
||||||
|
Dsn = new Dsn("https://5e342cd55f294edebdc9ad604d28bbd3@sentry.io/1255255"),
|
||||||
|
Release = game.Version
|
||||||
|
};
|
||||||
|
|
||||||
|
sentry = new SentryClient(options);
|
||||||
|
sentryScope = new Scope(options);
|
||||||
|
|
||||||
Exception lastException = null;
|
Exception lastException = null;
|
||||||
|
|
||||||
Logger.NewEntry += entry =>
|
Logger.NewEntry += entry =>
|
||||||
@ -46,10 +49,10 @@ namespace osu.Game.Utils
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
lastException = exception;
|
lastException = exception;
|
||||||
queuePendingTask(raven.CaptureAsync(new SentryEvent(exception) { Message = entry.Message }));
|
sentry.CaptureEvent(new SentryEvent(exception) { Message = entry.Message }, sentryScope);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
raven.AddTrail(new Breadcrumb(entry.Target.ToString(), BreadcrumbType.Navigation) { Message = entry.Message });
|
sentryScope.AddBreadcrumb(DateTimeOffset.Now, entry.Message, entry.Target.ToString(), "navigation");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,19 +84,9 @@ namespace osu.Game.Utils
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void queuePendingTask(Task<string> task)
|
|
||||||
{
|
|
||||||
lock (tasks) tasks.Add(task);
|
|
||||||
task.ContinueWith(_ =>
|
|
||||||
{
|
|
||||||
lock (tasks)
|
|
||||||
tasks.Remove(task);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Disposal
|
#region Disposal
|
||||||
|
|
||||||
~RavenLogger()
|
~SentryLogger()
|
||||||
{
|
{
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
}
|
}
|
||||||
@ -112,7 +105,9 @@ namespace osu.Game.Utils
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
isDisposed = true;
|
isDisposed = true;
|
||||||
lock (tasks) Task.WaitAll(tasks.ToArray(), 5000);
|
sentry?.Dispose();
|
||||||
|
sentry = null;
|
||||||
|
sentryScope = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
@ -22,9 +22,9 @@
|
|||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1121.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2019.1121.0" />
|
||||||
|
<PackageReference Include="Sentry" Version="1.2.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.6.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="4.6.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
Loading…
Reference in New Issue
Block a user