mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 11:42:56 +08:00
Merge branch 'master' into comment-editor-1
This commit is contained in:
commit
4a747182b4
@ -52,7 +52,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.1127.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.1126.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.1130.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||
|
@ -7,12 +7,14 @@ using osu.Framework.Graphics.Shapes;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Background
|
||||
{
|
||||
public partial class TestSceneTrianglesV2Background : OsuTestScene
|
||||
{
|
||||
private readonly TrianglesV2 triangles;
|
||||
private readonly Box box;
|
||||
|
||||
public TestSceneTrianglesV2Background()
|
||||
{
|
||||
@ -23,27 +25,44 @@ namespace osu.Game.Tests.Visual.Background
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Gray
|
||||
},
|
||||
new Container
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(500, 100),
|
||||
Masking = true,
|
||||
CornerRadius = 40,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Red
|
||||
Size = new Vector2(500, 100),
|
||||
Masking = true,
|
||||
CornerRadius = 40,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Red
|
||||
},
|
||||
triangles = new TrianglesV2
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
}
|
||||
},
|
||||
triangles = new TrianglesV2
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ColourTop = Color4.White,
|
||||
ColourBottom = Color4.Red
|
||||
Size = new Vector2(500, 100),
|
||||
Masking = true,
|
||||
CornerRadius = 40,
|
||||
Child = box = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,8 +73,16 @@ namespace osu.Game.Tests.Visual.Background
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
AddSliderStep("Spawn ratio", 0f, 2f, 1f, s => triangles.SpawnRatio = s);
|
||||
AddSliderStep("Spawn ratio", 0f, 10f, 1f, s =>
|
||||
{
|
||||
triangles.SpawnRatio = s;
|
||||
triangles.Reset(1234);
|
||||
});
|
||||
AddSliderStep("Thickness", 0f, 1f, 0.02f, t => triangles.Thickness = t);
|
||||
|
||||
AddStep("White colour", () => box.Colour = triangles.Colour = Color4.White);
|
||||
AddStep("Vertical gradient", () => box.Colour = triangles.Colour = ColourInfo.GradientVertical(Color4.White, Color4.Red));
|
||||
AddStep("Horizontal gradient", () => box.Colour = triangles.Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.Red));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Screens.Edit;
|
||||
@ -26,6 +28,7 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||
|
||||
private TimingScreen timingScreen;
|
||||
private EditorBeatmap editorBeatmap;
|
||||
|
||||
protected override bool ScrollUsingMouseWheel => false;
|
||||
|
||||
@ -35,8 +38,11 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
|
||||
Beatmap.Value = CreateWorkingBeatmap(Ruleset.Value);
|
||||
Beatmap.Disabled = true;
|
||||
}
|
||||
|
||||
var editorBeatmap = new EditorBeatmap(Beatmap.Value.GetPlayableBeatmap(Ruleset.Value));
|
||||
private void reloadEditorBeatmap()
|
||||
{
|
||||
editorBeatmap = new EditorBeatmap(Beatmap.Value.GetPlayableBeatmap(Ruleset.Value));
|
||||
|
||||
Child = new DependencyProvidingContainer
|
||||
{
|
||||
@ -58,7 +64,9 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
AddStep("Stop clock", () => EditorClock.Stop());
|
||||
|
||||
AddUntilStep("wait for rows to load", () => Child.ChildrenOfType<EffectRowAttribute>().Any());
|
||||
AddStep("Reload Editor Beatmap", reloadEditorBeatmap);
|
||||
|
||||
AddUntilStep("Wait for rows to load", () => Child.ChildrenOfType<EffectRowAttribute>().Any());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -95,6 +103,37 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 69670);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestScrollControlGroupIntoView()
|
||||
{
|
||||
AddStep("Add many control points", () =>
|
||||
{
|
||||
editorBeatmap.ControlPointInfo.Clear();
|
||||
|
||||
editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint());
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
editorBeatmap.ControlPointInfo.Add((i + 1) * 1000, new EffectControlPoint
|
||||
{
|
||||
KiaiMode = Convert.ToBoolean(i % 2),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
AddStep("Select first effect point", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(Child.ChildrenOfType<EffectRowAttribute>().First());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddStep("Seek to beginning", () => EditorClock.Seek(0));
|
||||
|
||||
AddStep("Seek to last point", () => EditorClock.Seek(101 * 1000));
|
||||
|
||||
AddUntilStep("Scrolled to end", () => timingScreen.ChildrenOfType<OsuScrollContainer>().First().IsScrolledToEnd());
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
Beatmap.Disabled = false;
|
||||
|
@ -130,11 +130,11 @@ namespace osu.Game.Tests.Visual.Online
|
||||
|
||||
Color4 textColour = isAction && hasBackground ? Color4Extensions.FromHex(newLine.Message.Sender.Colour) : Color4.White;
|
||||
|
||||
var linkCompilers = newLine.ContentFlow.Where(d => d is DrawableLinkCompiler).ToList();
|
||||
var linkCompilers = newLine.DrawableContentFlow.Where(d => d is DrawableLinkCompiler).ToList();
|
||||
var linkSprites = linkCompilers.SelectMany(comp => ((DrawableLinkCompiler)comp).Parts);
|
||||
|
||||
return linkSprites.All(d => d.Colour == linkColour)
|
||||
&& newLine.ContentFlow.Except(linkSprites.Concat(linkCompilers)).All(d => d.Colour == textColour);
|
||||
&& newLine.DrawableContentFlow.Except(linkSprites.Concat(linkCompilers)).All(d => d.Colour == textColour);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Online
|
||||
@ -33,7 +34,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
AddStep("Set activity", () => api.Activity.Value = new UserActivity.InLobby(null));
|
||||
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand()));
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand(new Channel())));
|
||||
|
||||
AddAssert("Check correct response", () => postTarget.LastMessage.Contains("is listening"));
|
||||
}
|
||||
@ -43,7 +44,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
AddStep("Set activity", () => api.Activity.Value = new UserActivity.Editing(new BeatmapInfo()));
|
||||
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand()));
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand(new Channel())));
|
||||
|
||||
AddAssert("Check correct response", () => postTarget.LastMessage.Contains("is editing"));
|
||||
}
|
||||
@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
AddStep("Set activity", () => api.Activity.Value = new UserActivity.InSoloGame(new BeatmapInfo(), new RulesetInfo()));
|
||||
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand()));
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand(new Channel())));
|
||||
|
||||
AddAssert("Check correct response", () => postTarget.LastMessage.Contains("is playing"));
|
||||
}
|
||||
@ -69,7 +70,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
BeatmapInfo = { OnlineID = hasOnlineId ? 1234 : -1 }
|
||||
});
|
||||
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand()));
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand(new Channel())));
|
||||
|
||||
if (hasOnlineId)
|
||||
AddAssert("Check link presence", () => postTarget.LastMessage.Contains("/b/1234"));
|
||||
@ -77,6 +78,18 @@ namespace osu.Game.Tests.Visual.Online
|
||||
AddAssert("Check link not present", () => !postTarget.LastMessage.Contains("https://"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestModPresence()
|
||||
{
|
||||
AddStep("Set activity", () => api.Activity.Value = new UserActivity.InSoloGame(new BeatmapInfo(), new RulesetInfo()));
|
||||
|
||||
AddStep("Add Hidden mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod<ModHidden>() });
|
||||
|
||||
AddStep("Run command", () => Add(new NowPlayingCommand(new Channel())));
|
||||
|
||||
AddAssert("Check mod is present", () => postTarget.LastMessage.Contains("+HD"));
|
||||
}
|
||||
|
||||
public partial class PostTarget : Component, IChannelPostTarget
|
||||
{
|
||||
public void PostMessage(string text, bool isAction = false, Channel target = null)
|
||||
|
@ -62,7 +62,6 @@ namespace osu.Game.Tests.Visual.Settings
|
||||
section.Children.Where(f => f.IsPresent)
|
||||
.OfType<ISettingsItem>()
|
||||
.OfType<IFilterable>()
|
||||
.Where(f => !(f is IHasFilterableChildren))
|
||||
.All(f => f.FilterTerms.Any(t => t.ToString().Contains("scaling")))
|
||||
));
|
||||
|
||||
|
@ -1,28 +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 NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Select;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
public partial class TestSceneDifficultyRangeFilterControl : OsuTestScene
|
||||
{
|
||||
[Test]
|
||||
public void TestBasic()
|
||||
{
|
||||
AddStep("create control", () =>
|
||||
{
|
||||
Child = new DifficultyRangeFilterControl
|
||||
{
|
||||
Width = 200,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(3),
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
79
osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs
Normal file
79
osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs
Normal file
@ -0,0 +1,79 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.UserInterface
|
||||
{
|
||||
public partial class TestSceneRangeSlider : OsuTestScene
|
||||
{
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red);
|
||||
|
||||
private readonly BindableNumber<double> customStart = new BindableNumber<double>
|
||||
{
|
||||
MinValue = 0,
|
||||
MaxValue = 100,
|
||||
Precision = 0.1f
|
||||
};
|
||||
|
||||
private readonly BindableNumber<double> customEnd = new BindableNumber<double>(100)
|
||||
{
|
||||
MinValue = 0,
|
||||
MaxValue = 100,
|
||||
Precision = 0.1f
|
||||
};
|
||||
|
||||
private RangeSlider rangeSlider = null!;
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetUpSteps()
|
||||
{
|
||||
AddStep("create control", () => Child = rangeSlider = new RangeSlider
|
||||
{
|
||||
Width = 200,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(3),
|
||||
LowerBound = customStart,
|
||||
UpperBound = customEnd,
|
||||
TooltipSuffix = "suffix",
|
||||
NubWidth = Nub.HEIGHT * 2,
|
||||
DefaultStringLowerBound = "Start",
|
||||
DefaultStringUpperBound = "End",
|
||||
MinRange = 10
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAdjustRange()
|
||||
{
|
||||
AddAssert("Initial lower bound is correct", () => rangeSlider.LowerBound.Value, () => Is.EqualTo(0).Within(0.1f));
|
||||
AddAssert("Initial upper bound is correct", () => rangeSlider.UpperBound.Value, () => Is.EqualTo(100).Within(0.1f));
|
||||
|
||||
AddStep("Adjust range", () =>
|
||||
{
|
||||
customStart.Value = 50;
|
||||
customEnd.Value = 75;
|
||||
});
|
||||
|
||||
AddAssert("Adjusted lower bound is correct", () => rangeSlider.LowerBound.Value, () => Is.EqualTo(50).Within(0.1f));
|
||||
AddAssert("Adjusted upper bound is correct", () => rangeSlider.UpperBound.Value, () => Is.EqualTo(75).Within(0.1f));
|
||||
|
||||
AddStep("Test nub pushing", () =>
|
||||
{
|
||||
customStart.Value = 90;
|
||||
});
|
||||
|
||||
AddAssert("Pushed lower bound is correct", () => rangeSlider.LowerBound.Value, () => Is.EqualTo(90).Within(0.1f));
|
||||
AddAssert("Pushed upper bound is correct", () => rangeSlider.UpperBound.Value, () => Is.EqualTo(100).Within(0.1f));
|
||||
}
|
||||
}
|
||||
}
|
@ -11,9 +11,7 @@ using osu.Framework.Allocation;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics.Rendering;
|
||||
using osu.Framework.Graphics.Rendering.Vertices;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
|
||||
@ -23,28 +21,12 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
{
|
||||
private const float triangle_size = 100;
|
||||
private const float base_velocity = 50;
|
||||
private const int texture_height = 128;
|
||||
|
||||
/// <summary>
|
||||
/// sqrt(3) / 2
|
||||
/// </summary>
|
||||
private const float equilateral_triangle_ratio = 0.866f;
|
||||
|
||||
private readonly Bindable<Color4> colourTop = new Bindable<Color4>(Color4.White);
|
||||
private readonly Bindable<Color4> colourBottom = new Bindable<Color4>(Color4.Black);
|
||||
|
||||
public Color4 ColourTop
|
||||
{
|
||||
get => colourTop.Value;
|
||||
set => colourTop.Value = value;
|
||||
}
|
||||
|
||||
public Color4 ColourBottom
|
||||
{
|
||||
get => colourBottom.Value;
|
||||
set => colourBottom.Value = value;
|
||||
}
|
||||
|
||||
public float Thickness { get; set; } = 0.02f; // No need for invalidation since it's happening in Update()
|
||||
|
||||
/// <summary>
|
||||
@ -70,9 +52,6 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
|
||||
private readonly List<TriangleParticle> parts = new List<TriangleParticle>();
|
||||
|
||||
[Resolved]
|
||||
private IRenderer renderer { get; set; } = null!;
|
||||
|
||||
private Random? stableRandom;
|
||||
|
||||
private IShader shader = null!;
|
||||
@ -89,42 +68,19 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ShaderManager shaders)
|
||||
private void load(ShaderManager shaders, IRenderer renderer)
|
||||
{
|
||||
shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, "TriangleBorder");
|
||||
texture = renderer.WhitePixel;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
colourTop.BindValueChanged(_ => updateTexture());
|
||||
colourBottom.BindValueChanged(_ => updateTexture(), true);
|
||||
|
||||
spawnRatio.BindValueChanged(_ => Reset(), true);
|
||||
}
|
||||
|
||||
private void updateTexture()
|
||||
{
|
||||
var image = new Image<Rgba32>(texture_height, 1);
|
||||
|
||||
texture = renderer.CreateTexture(1, texture_height, true);
|
||||
|
||||
for (int i = 0; i < texture_height; i++)
|
||||
{
|
||||
float ratio = (float)i / texture_height;
|
||||
|
||||
image[i, 0] = new Rgba32(
|
||||
colourBottom.Value.R * ratio + colourTop.Value.R * (1f - ratio),
|
||||
colourBottom.Value.G * ratio + colourTop.Value.G * (1f - ratio),
|
||||
colourBottom.Value.B * ratio + colourTop.Value.B * (1f - ratio)
|
||||
);
|
||||
}
|
||||
|
||||
texture.SetData(new TextureUpload(image));
|
||||
Invalidate(Invalidation.DrawNode);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
@ -227,6 +183,9 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
private Texture texture = null!;
|
||||
|
||||
private readonly List<TriangleParticle> parts = new List<TriangleParticle>();
|
||||
|
||||
private readonly Vector2 triangleSize = new Vector2(1f, equilateral_triangle_ratio) * triangle_size;
|
||||
|
||||
private Vector2 size;
|
||||
private float thickness;
|
||||
private float texelSize;
|
||||
@ -246,7 +205,15 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
texture = Source.texture;
|
||||
size = Source.DrawSize;
|
||||
thickness = Source.Thickness;
|
||||
texelSize = Math.Max(1.5f / Source.ScreenSpaceDrawQuad.Size.X, 1.5f / Source.ScreenSpaceDrawQuad.Size.Y);
|
||||
|
||||
Quad triangleQuad = new Quad(
|
||||
Vector2Extensions.Transform(Vector2.Zero, DrawInfo.Matrix),
|
||||
Vector2Extensions.Transform(new Vector2(triangle_size, 0f), DrawInfo.Matrix),
|
||||
Vector2Extensions.Transform(new Vector2(0f, triangleSize.Y), DrawInfo.Matrix),
|
||||
Vector2Extensions.Transform(triangleSize, DrawInfo.Matrix)
|
||||
);
|
||||
|
||||
texelSize = 1.5f / triangleQuad.Height;
|
||||
|
||||
parts.Clear();
|
||||
parts.AddRange(Source.parts);
|
||||
@ -256,7 +223,7 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
{
|
||||
base.Draw(renderer);
|
||||
|
||||
if (Source.AimCount == 0)
|
||||
if (Source.AimCount == 0 || thickness == 0)
|
||||
return;
|
||||
|
||||
if (vertexBatch == null || vertexBatch.Size != Source.AimCount)
|
||||
@ -269,35 +236,42 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
shader.GetUniform<float>("thickness").UpdateValue(ref thickness);
|
||||
shader.GetUniform<float>("texelSize").UpdateValue(ref texelSize);
|
||||
|
||||
float relativeHeight = triangleSize.Y / size.Y;
|
||||
float relativeWidth = triangleSize.X / size.X;
|
||||
|
||||
foreach (TriangleParticle particle in parts)
|
||||
{
|
||||
var offset = triangle_size * new Vector2(0.5f, equilateral_triangle_ratio);
|
||||
|
||||
Vector2 topLeft = particle.Position * size + new Vector2(-offset.X, 0f);
|
||||
Vector2 topRight = particle.Position * size + new Vector2(offset.X, 0);
|
||||
Vector2 bottomLeft = particle.Position * size + new Vector2(-offset.X, offset.Y);
|
||||
Vector2 bottomRight = particle.Position * size + new Vector2(offset.X, offset.Y);
|
||||
Vector2 topLeft = particle.Position - new Vector2(relativeWidth * 0.5f, 0f);
|
||||
Vector2 topRight = topLeft + new Vector2(relativeWidth, 0f);
|
||||
Vector2 bottomLeft = topLeft + new Vector2(0f, relativeHeight);
|
||||
Vector2 bottomRight = bottomLeft + new Vector2(relativeWidth, 0f);
|
||||
|
||||
var drawQuad = new Quad(
|
||||
Vector2Extensions.Transform(topLeft, DrawInfo.Matrix),
|
||||
Vector2Extensions.Transform(topRight, DrawInfo.Matrix),
|
||||
Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix),
|
||||
Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix)
|
||||
Vector2Extensions.Transform(topLeft * size, DrawInfo.Matrix),
|
||||
Vector2Extensions.Transform(topRight * size, DrawInfo.Matrix),
|
||||
Vector2Extensions.Transform(bottomLeft * size, DrawInfo.Matrix),
|
||||
Vector2Extensions.Transform(bottomRight * size, DrawInfo.Matrix)
|
||||
);
|
||||
|
||||
var tRect = new Quad(
|
||||
topLeft.X / size.X,
|
||||
topLeft.Y / size.Y * texture_height,
|
||||
(topRight.X - topLeft.X) / size.X,
|
||||
(bottomRight.Y - topRight.Y) / size.Y * texture_height
|
||||
).AABBFloat;
|
||||
ColourInfo colourInfo = triangleColourInfo(DrawColourInfo.Colour, new Quad(topLeft, topRight, bottomLeft, bottomRight));
|
||||
|
||||
renderer.DrawQuad(texture, drawQuad, DrawColourInfo.Colour, tRect, vertexBatch.AddAction, textureCoords: tRect);
|
||||
renderer.DrawQuad(texture, drawQuad, colourInfo, vertexAction: vertexBatch.AddAction);
|
||||
}
|
||||
|
||||
shader.Unbind();
|
||||
}
|
||||
|
||||
private static ColourInfo triangleColourInfo(ColourInfo source, Quad quad)
|
||||
{
|
||||
return new ColourInfo
|
||||
{
|
||||
TopLeft = source.Interpolate(quad.TopLeft),
|
||||
TopRight = source.Interpolate(quad.TopRight),
|
||||
BottomLeft = source.Interpolate(quad.BottomLeft),
|
||||
BottomRight = source.Interpolate(quad.BottomRight)
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
212
osu.Game/Graphics/UserInterface/RangeSlider.cs
Normal file
212
osu.Game/Graphics/UserInterface/RangeSlider.cs
Normal file
@ -0,0 +1,212 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public partial class RangeSlider : CompositeDrawable
|
||||
{
|
||||
/// <summary>
|
||||
/// The lower limiting value
|
||||
/// </summary>
|
||||
public Bindable<double> LowerBound
|
||||
{
|
||||
get => lowerBound.Current;
|
||||
set => lowerBound.Current = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The upper limiting value
|
||||
/// </summary>
|
||||
public Bindable<double> UpperBound
|
||||
{
|
||||
get => upperBound.Current;
|
||||
set => upperBound.Current = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Text that describes this RangeSlider's functionality
|
||||
/// </summary>
|
||||
public string Label
|
||||
{
|
||||
set => label.Text = value;
|
||||
}
|
||||
|
||||
public float NubWidth
|
||||
{
|
||||
set => lowerBound.NubWidth = upperBound.NubWidth = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimum difference between the lower bound and higher bound
|
||||
/// </summary>
|
||||
public float MinRange
|
||||
{
|
||||
set => minRange = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// lower bound display for when it is set to its default value
|
||||
/// </summary>
|
||||
public string DefaultStringLowerBound
|
||||
{
|
||||
set => lowerBound.DefaultString = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// upper bound display for when it is set to its default value
|
||||
/// </summary>
|
||||
public string DefaultStringUpperBound
|
||||
{
|
||||
set => upperBound.DefaultString = value;
|
||||
}
|
||||
|
||||
public LocalisableString DefaultTooltipLowerBound
|
||||
{
|
||||
set => lowerBound.DefaultTooltip = value;
|
||||
}
|
||||
|
||||
public LocalisableString DefaultTooltipUpperBound
|
||||
{
|
||||
set => upperBound.DefaultTooltip = value;
|
||||
}
|
||||
|
||||
public string TooltipSuffix
|
||||
{
|
||||
set => upperBound.TooltipSuffix = lowerBound.TooltipSuffix = value;
|
||||
}
|
||||
|
||||
private float minRange = 0.1f;
|
||||
|
||||
private readonly OsuSpriteText label;
|
||||
|
||||
private readonly LowerBoundSlider lowerBound;
|
||||
private readonly UpperBoundSlider upperBound;
|
||||
|
||||
public RangeSlider()
|
||||
{
|
||||
const float vertical_offset = 13;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
label = new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.GetFont(size: 14),
|
||||
},
|
||||
upperBound = new UpperBoundSlider
|
||||
{
|
||||
KeyboardStep = 0.1f,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Y = vertical_offset,
|
||||
},
|
||||
lowerBound = new LowerBoundSlider
|
||||
{
|
||||
KeyboardStep = 0.1f,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Y = vertical_offset,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
lowerBound.Current.ValueChanged += min => upperBound.Current.Value = Math.Max(min.NewValue + minRange, upperBound.Current.Value);
|
||||
upperBound.Current.ValueChanged += max => lowerBound.Current.Value = Math.Min(max.NewValue - minRange, lowerBound.Current.Value);
|
||||
}
|
||||
|
||||
private partial class LowerBoundSlider : BoundSlider
|
||||
{
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
LeftBox.Height = 6; // hide any colour bleeding from overlap
|
||||
|
||||
AccentColour = BackgroundColour;
|
||||
BackgroundColour = Color4.Transparent;
|
||||
}
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
|
||||
base.ReceivePositionalInputAt(screenSpacePos)
|
||||
&& screenSpacePos.X <= Nub.ScreenSpaceDrawQuad.TopRight.X;
|
||||
}
|
||||
|
||||
private partial class UpperBoundSlider : BoundSlider
|
||||
{
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
RightBox.Height = 6; // just to match the left bar height really
|
||||
}
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
|
||||
base.ReceivePositionalInputAt(screenSpacePos)
|
||||
&& screenSpacePos.X >= Nub.ScreenSpaceDrawQuad.TopLeft.X;
|
||||
}
|
||||
|
||||
protected partial class BoundSlider : OsuSliderBar<double>
|
||||
{
|
||||
public string? DefaultString;
|
||||
public LocalisableString? DefaultTooltip;
|
||||
public string? TooltipSuffix;
|
||||
public float NubWidth { get; set; } = Nub.HEIGHT;
|
||||
|
||||
public override LocalisableString TooltipText =>
|
||||
(Current.IsDefault ? DefaultTooltip : Current.Value.ToString($@"0.## {TooltipSuffix}")) ?? Current.Value.ToString($@"0.## {TooltipSuffix}");
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
base.OnHover(e);
|
||||
return true; // Make sure only one nub shows hover effect at once.
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
Nub.Width = NubWidth;
|
||||
RangePadding = Nub.Width / 2;
|
||||
|
||||
OsuSpriteText currentDisplay;
|
||||
|
||||
Nub.Add(currentDisplay = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Y = -0.5f,
|
||||
Colour = Color4.White,
|
||||
Font = OsuFont.Torus.With(size: 10),
|
||||
});
|
||||
|
||||
Current.BindValueChanged(current =>
|
||||
{
|
||||
currentDisplay.Text = (current.NewValue != Current.Default ? current.NewValue.ToString("N1") : DefaultString) ?? current.NewValue.ToString("N1");
|
||||
}, true);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider? colourProvider)
|
||||
{
|
||||
if (colourProvider == null) return;
|
||||
|
||||
AccentColour = colourProvider.Background2;
|
||||
Nub.AccentColour = colourProvider.Background2;
|
||||
Nub.GlowingAccentColour = colourProvider.Background1;
|
||||
Nub.GlowColour = colourProvider.Background2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ using System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
@ -79,8 +80,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
|
||||
|
||||
Debug.Assert(triangleGradientSecondColour != null);
|
||||
|
||||
Triangles.ColourTop = triangleGradientSecondColour.Value;
|
||||
Triangles.ColourBottom = BackgroundColour;
|
||||
Triangles.Colour = ColourInfo.GradientVertical(triangleGradientSecondColour.Value, BackgroundColour);
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
|
@ -25,6 +25,7 @@ namespace osu.Game.Online.API.Requests
|
||||
var req = base.CreateWebRequest();
|
||||
if (channel != null) req.AddParameter(@"channel", channel.Id.ToString());
|
||||
req.AddParameter(@"since", since.ToString());
|
||||
req.AddParameter(@"includes[]", "presence");
|
||||
|
||||
return req;
|
||||
}
|
||||
|
@ -16,5 +16,7 @@ namespace osu.Game.Online.API.Requests
|
||||
|
||||
[JsonProperty]
|
||||
public List<Message> Messages;
|
||||
|
||||
// TODO: Handle Silences here (will need to add to includes[] in the request).
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,17 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
@ -15,21 +19,30 @@ namespace osu.Game.Online.Chat
|
||||
public partial class NowPlayingCommand : Component
|
||||
{
|
||||
[Resolved]
|
||||
private IChannelPostTarget channelManager { get; set; }
|
||||
private IChannelPostTarget channelManager { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private Bindable<WorkingBeatmap> currentBeatmap { get; set; }
|
||||
private Bindable<WorkingBeatmap> currentBeatmap { get; set; } = null!;
|
||||
|
||||
private readonly Channel target;
|
||||
[Resolved]
|
||||
private Bindable<IReadOnlyList<Mod>> selectedMods { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private IBindable<RulesetInfo> currentRuleset { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private LocalisationManager localisation { get; set; } = null!;
|
||||
|
||||
private readonly Channel? target;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="NowPlayingCommand"/> to post the currently-playing beatmap to a parenting <see cref="IChannelPostTarget"/>.
|
||||
/// </summary>
|
||||
/// <param name="target">The target channel to post to. If <c>null</c>, the currently-selected channel will be posted to.</param>
|
||||
public NowPlayingCommand(Channel target = null)
|
||||
public NowPlayingCommand(Channel target)
|
||||
{
|
||||
this.target = target;
|
||||
}
|
||||
@ -59,10 +72,55 @@ namespace osu.Game.Online.Chat
|
||||
break;
|
||||
}
|
||||
|
||||
string beatmapString = beatmapInfo.OnlineID > 0 ? $"[{api.WebsiteRootUrl}/b/{beatmapInfo.OnlineID} {beatmapInfo}]" : beatmapInfo.ToString();
|
||||
string[] pieces =
|
||||
{
|
||||
"is",
|
||||
verb,
|
||||
getBeatmapPart(),
|
||||
getRulesetPart(),
|
||||
getModPart(),
|
||||
};
|
||||
|
||||
channelManager.PostMessage($"is {verb} {beatmapString}", true, target);
|
||||
channelManager.PostMessage(string.Join(' ', pieces.Where(p => !string.IsNullOrEmpty(p))), true, target);
|
||||
Expire();
|
||||
|
||||
string getBeatmapPart()
|
||||
{
|
||||
string beatmapInfoString = localisation.GetLocalisedBindableString(beatmapInfo.GetDisplayTitleRomanisable()).Value;
|
||||
|
||||
return beatmapInfo.OnlineID > 0 ? $"[{api.WebsiteRootUrl}/b/{beatmapInfo.OnlineID} {beatmapInfoString}]" : beatmapInfoString;
|
||||
}
|
||||
|
||||
string getRulesetPart()
|
||||
{
|
||||
if (api.Activity.Value is not UserActivity.InGame) return string.Empty;
|
||||
|
||||
return $"<{currentRuleset.Value.Name}>";
|
||||
}
|
||||
|
||||
string getModPart()
|
||||
{
|
||||
if (api.Activity.Value is not UserActivity.InGame) return string.Empty;
|
||||
|
||||
if (selectedMods.Value.Count == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
StringBuilder modsString = new StringBuilder();
|
||||
|
||||
foreach (var mod in selectedMods.Value.Where(mod => mod.Type == ModType.DifficultyIncrease))
|
||||
{
|
||||
modsString.Append($"+{mod.Acronym} ");
|
||||
}
|
||||
|
||||
foreach (var mod in selectedMods.Value.Where(mod => mod.Type != ModType.DifficultyIncrease))
|
||||
{
|
||||
modsString.Append($"-{mod.Acronym} ");
|
||||
}
|
||||
|
||||
return modsString.ToString().Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
protected partial class StandAloneMessage : ChatLine
|
||||
{
|
||||
protected override float TextSize => 15;
|
||||
protected override float FontSize => 15;
|
||||
protected override float Spacing => 5;
|
||||
protected override float UsernameWidth => 75;
|
||||
|
||||
|
@ -33,11 +33,11 @@ namespace osu.Game.Online.Notifications
|
||||
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
API.Queue(CreateFetchMessagesRequest(0));
|
||||
API.Queue(CreateInitialFetchRequest(0));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
protected APIRequest CreateFetchMessagesRequest(long? lastMessageId = null)
|
||||
protected APIRequest CreateInitialFetchRequest(long? lastMessageId = null)
|
||||
{
|
||||
var fetchReq = new GetUpdatesRequest(lastMessageId ?? this.lastMessageId);
|
||||
|
||||
@ -67,8 +67,11 @@ namespace osu.Game.Online.Notifications
|
||||
|
||||
protected void HandleChannelParted(Channel channel) => ChannelParted?.Invoke(channel);
|
||||
|
||||
protected void HandleMessages(List<Message> messages)
|
||||
protected void HandleMessages(List<Message>? messages)
|
||||
{
|
||||
if (messages == null)
|
||||
return;
|
||||
|
||||
NewMessages?.Invoke(messages);
|
||||
lastMessageId = Math.Max(lastMessageId, messages.LastOrDefault()?.Id ?? 0);
|
||||
}
|
||||
|
@ -7,8 +7,6 @@ using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Online.Rooms
|
||||
{
|
||||
// TODO: Remove disable below after merging https://github.com/ppy/osu-framework/pull/5548 and applying follow-up changes game-side.
|
||||
// ReSharper disable once PartialTypeWithSinglePart
|
||||
public partial class APICreatedRoom : Room
|
||||
{
|
||||
[JsonProperty("error")]
|
||||
|
@ -16,7 +16,7 @@ using osu.Game.Online.Rooms.RoomStatuses;
|
||||
namespace osu.Game.Online.Rooms
|
||||
{
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public partial class Room
|
||||
public partial class Room : IDependencyInjectionCandidate
|
||||
{
|
||||
[Cached]
|
||||
[JsonProperty("id")]
|
||||
|
@ -1,7 +1,6 @@
|
||||
// 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.Linq;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
@ -9,25 +8,20 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Chat;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public partial class ChatLine : CompositeDrawable
|
||||
{
|
||||
private Message message = null!;
|
||||
|
||||
public Message Message
|
||||
{
|
||||
get => message;
|
||||
@ -44,49 +38,35 @@ namespace osu.Game.Overlays.Chat
|
||||
}
|
||||
}
|
||||
|
||||
public LinkFlowContainer ContentFlow { get; private set; } = null!;
|
||||
public IReadOnlyCollection<Drawable> DrawableContentFlow => drawableContentFlow;
|
||||
|
||||
protected virtual float TextSize => 20;
|
||||
protected virtual float FontSize => 20;
|
||||
|
||||
protected virtual float Spacing => 15;
|
||||
|
||||
protected virtual float UsernameWidth => 130;
|
||||
|
||||
private Color4 usernameColour;
|
||||
|
||||
private OsuSpriteText timestamp = null!;
|
||||
|
||||
private Message message = null!;
|
||||
|
||||
private OsuSpriteText username = null!;
|
||||
|
||||
private Container? highlight;
|
||||
|
||||
private readonly Bindable<bool> prefer24HourTime = new Bindable<bool>();
|
||||
|
||||
private bool senderHasColour => !string.IsNullOrEmpty(message.Sender.Colour);
|
||||
|
||||
private bool messageHasColour => Message.IsAction && senderHasColour;
|
||||
|
||||
[Resolved]
|
||||
private ChannelManager? chatManager { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; } = null!;
|
||||
private OverlayColourProvider? colourProvider { get; set; }
|
||||
|
||||
private readonly OsuSpriteText drawableTimestamp;
|
||||
|
||||
private readonly DrawableUsername drawableUsername;
|
||||
|
||||
private readonly LinkFlowContainer drawableContentFlow;
|
||||
|
||||
private readonly Bindable<bool> prefer24HourTime = new Bindable<bool>();
|
||||
|
||||
private Container? highlight;
|
||||
|
||||
public ChatLine(Message message)
|
||||
{
|
||||
Message = message;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider? colourProvider, OsuConfigManager configManager)
|
||||
{
|
||||
usernameColour = senderHasColour
|
||||
? Color4Extensions.FromHex(message.Sender.Colour)
|
||||
: username_colours[message.Sender.Id % username_colours.Length];
|
||||
|
||||
InternalChild = new GridContainer
|
||||
{
|
||||
@ -103,30 +83,24 @@ namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
timestamp = new OsuSpriteText
|
||||
drawableTimestamp = new OsuSpriteText
|
||||
{
|
||||
Shadow = false,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true),
|
||||
Colour = colourProvider?.Background1 ?? Colour4.White,
|
||||
Font = OsuFont.GetFont(size: FontSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true),
|
||||
AlwaysPresent = true,
|
||||
},
|
||||
new MessageSender(message.Sender)
|
||||
drawableUsername = new DrawableUsername(message.Sender)
|
||||
{
|
||||
Width = UsernameWidth,
|
||||
FontSize = FontSize,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Origin = Anchor.TopRight,
|
||||
Anchor = Anchor.TopRight,
|
||||
Child = createUsername(),
|
||||
Margin = new MarginPadding { Horizontal = Spacing },
|
||||
},
|
||||
ContentFlow = new LinkFlowContainer(t =>
|
||||
{
|
||||
t.Shadow = false;
|
||||
t.Font = t.Font.With(size: TextSize, italics: Message.IsAction);
|
||||
t.Colour = messageHasColour ? Color4Extensions.FromHex(message.Sender.Colour) : colourProvider?.Content1 ?? Colour4.White;
|
||||
})
|
||||
drawableContentFlow = new LinkFlowContainer(styleMessageContent)
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -134,18 +108,23 @@ namespace osu.Game.Overlays.Chat
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager configManager)
|
||||
{
|
||||
configManager.BindWith(OsuSetting.Prefer24HourTime, prefer24HourTime);
|
||||
prefer24HourTime.BindValueChanged(_ => updateTimestamp());
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
drawableTimestamp.Colour = colourProvider?.Background1 ?? Colour4.White;
|
||||
|
||||
updateMessageContent();
|
||||
FinishTransforms(true);
|
||||
|
||||
prefer24HourTime.BindValueChanged(_ => updateTimestamp());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -160,7 +139,7 @@ namespace osu.Game.Overlays.Chat
|
||||
CornerRadius = 2f,
|
||||
Masking = true,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = usernameColour.Darken(1f),
|
||||
Colour = drawableUsername.AccentColour.Darken(1f),
|
||||
Depth = float.MaxValue,
|
||||
Child = new Box { RelativeSizeAxes = Axes.Both }
|
||||
});
|
||||
@ -170,166 +149,35 @@ namespace osu.Game.Overlays.Chat
|
||||
highlight.Expire();
|
||||
}
|
||||
|
||||
private void styleMessageContent(SpriteText text)
|
||||
{
|
||||
text.Shadow = false;
|
||||
text.Font = text.Font.With(size: FontSize, italics: Message.IsAction);
|
||||
|
||||
bool messageHasColour = Message.IsAction && !string.IsNullOrEmpty(message.Sender.Colour);
|
||||
text.Colour = messageHasColour ? Color4Extensions.FromHex(message.Sender.Colour) : colourProvider?.Content1 ?? Colour4.White;
|
||||
}
|
||||
|
||||
private void updateMessageContent()
|
||||
{
|
||||
this.FadeTo(message is LocalEchoMessage ? 0.4f : 1.0f, 500, Easing.OutQuint);
|
||||
timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint);
|
||||
drawableTimestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint);
|
||||
|
||||
updateTimestamp();
|
||||
username.Text = $@"{message.Sender.Username}";
|
||||
drawableUsername.Text = $@"{message.Sender.Username}";
|
||||
|
||||
// remove non-existent channels from the link list
|
||||
message.Links.RemoveAll(link => link.Action == LinkAction.OpenChannel && chatManager?.AvailableChannels.Any(c => c.Name == link.Argument.ToString()) != true);
|
||||
|
||||
ContentFlow.Clear();
|
||||
ContentFlow.AddLinks(message.DisplayContent, message.Links);
|
||||
drawableContentFlow.Clear();
|
||||
drawableContentFlow.AddLinks(message.DisplayContent, message.Links);
|
||||
}
|
||||
|
||||
private void updateTimestamp()
|
||||
{
|
||||
timestamp.Text = prefer24HourTime.Value
|
||||
drawableTimestamp.Text = prefer24HourTime.Value
|
||||
? $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"
|
||||
: $@"{message.Timestamp.LocalDateTime:hh:mm:ss tt}";
|
||||
}
|
||||
|
||||
private Drawable createUsername()
|
||||
{
|
||||
username = new OsuSpriteText
|
||||
{
|
||||
Shadow = false,
|
||||
Colour = senderHasColour ? colours.ChatBlue : usernameColour,
|
||||
Truncate = true,
|
||||
EllipsisString = "…",
|
||||
Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true),
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
MaxWidth = UsernameWidth,
|
||||
};
|
||||
|
||||
if (!senderHasColour)
|
||||
return username;
|
||||
|
||||
// Background effect
|
||||
return new Container
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
CornerRadius = 4,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Roundness = 1,
|
||||
Radius = 1,
|
||||
Colour = Color4.Black.Opacity(0.3f),
|
||||
Offset = new Vector2(0, 1),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
},
|
||||
Child = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
CornerRadius = 4,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = usernameColour,
|
||||
},
|
||||
new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 },
|
||||
Child = username
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private partial class MessageSender : OsuClickableContainer, IHasContextMenu
|
||||
{
|
||||
private readonly APIUser sender;
|
||||
|
||||
private Action startChatAction = null!;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
|
||||
public MessageSender(APIUser sender)
|
||||
{
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(UserProfileOverlay? profile, ChannelManager? chatManager, ChatOverlay? chatOverlay)
|
||||
{
|
||||
Action = () => profile?.ShowUser(sender);
|
||||
startChatAction = () =>
|
||||
{
|
||||
chatManager?.OpenPrivateChannel(sender);
|
||||
chatOverlay?.Show();
|
||||
};
|
||||
}
|
||||
|
||||
public MenuItem[] ContextMenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
if (sender.Equals(APIUser.SYSTEM_USER))
|
||||
return Array.Empty<MenuItem>();
|
||||
|
||||
List<MenuItem> items = new List<MenuItem>
|
||||
{
|
||||
new OsuMenuItem("View Profile", MenuItemType.Highlighted, Action)
|
||||
};
|
||||
|
||||
if (!sender.Equals(api.LocalUser.Value))
|
||||
items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, startChatAction));
|
||||
|
||||
return items.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Color4[] username_colours =
|
||||
{
|
||||
Color4Extensions.FromHex("588c7e"),
|
||||
Color4Extensions.FromHex("b2a367"),
|
||||
Color4Extensions.FromHex("c98f65"),
|
||||
Color4Extensions.FromHex("bc5151"),
|
||||
Color4Extensions.FromHex("5c8bd6"),
|
||||
Color4Extensions.FromHex("7f6ab7"),
|
||||
Color4Extensions.FromHex("a368ad"),
|
||||
Color4Extensions.FromHex("aa6880"),
|
||||
|
||||
Color4Extensions.FromHex("6fad9b"),
|
||||
Color4Extensions.FromHex("f2e394"),
|
||||
Color4Extensions.FromHex("f2ae72"),
|
||||
Color4Extensions.FromHex("f98f8a"),
|
||||
Color4Extensions.FromHex("7daef4"),
|
||||
Color4Extensions.FromHex("a691f2"),
|
||||
Color4Extensions.FromHex("c894d3"),
|
||||
Color4Extensions.FromHex("d895b0"),
|
||||
|
||||
Color4Extensions.FromHex("53c4a1"),
|
||||
Color4Extensions.FromHex("eace5c"),
|
||||
Color4Extensions.FromHex("ea8c47"),
|
||||
Color4Extensions.FromHex("fc4f4f"),
|
||||
Color4Extensions.FromHex("3d94ea"),
|
||||
Color4Extensions.FromHex("7760ea"),
|
||||
Color4Extensions.FromHex("af52c6"),
|
||||
Color4Extensions.FromHex("e25696"),
|
||||
|
||||
Color4Extensions.FromHex("677c66"),
|
||||
Color4Extensions.FromHex("9b8732"),
|
||||
Color4Extensions.FromHex("8c5129"),
|
||||
Color4Extensions.FromHex("8c3030"),
|
||||
Color4Extensions.FromHex("1f5d91"),
|
||||
Color4Extensions.FromHex("4335a5"),
|
||||
Color4Extensions.FromHex("812a96"),
|
||||
Color4Extensions.FromHex("992861"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
225
osu.Game/Overlays/Chat/DrawableUsername.cs
Normal file
225
osu.Game/Overlays/Chat/DrawableUsername.cs
Normal file
@ -0,0 +1,225 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Chat;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public partial class DrawableUsername : OsuClickableContainer, IHasContextMenu
|
||||
{
|
||||
public Color4 AccentColour { get; }
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
|
||||
Child.ReceivePositionalInputAt(screenSpacePos);
|
||||
|
||||
public float FontSize
|
||||
{
|
||||
set => drawableText.Font = OsuFont.GetFont(size: value, weight: FontWeight.Bold, italics: true);
|
||||
}
|
||||
|
||||
public LocalisableString Text
|
||||
{
|
||||
set => drawableText.Text = value;
|
||||
}
|
||||
|
||||
public override float Width
|
||||
{
|
||||
get => base.Width;
|
||||
set => base.Width = drawableText.MaxWidth = value;
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; } = null!;
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private ChannelManager? chatManager { get; set; }
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private ChatOverlay? chatOverlay { get; set; }
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private UserProfileOverlay? profileOverlay { get; set; }
|
||||
|
||||
private readonly APIUser user;
|
||||
private readonly OsuSpriteText drawableText;
|
||||
|
||||
private readonly Drawable colouredDrawable;
|
||||
|
||||
public DrawableUsername(APIUser user)
|
||||
{
|
||||
this.user = user;
|
||||
|
||||
Action = openUserProfile;
|
||||
|
||||
drawableText = new OsuSpriteText
|
||||
{
|
||||
Shadow = false,
|
||||
Truncate = true,
|
||||
EllipsisString = "…",
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
};
|
||||
|
||||
if (string.IsNullOrWhiteSpace(user.Colour))
|
||||
{
|
||||
AccentColour = default_colours[user.Id % default_colours.Length];
|
||||
|
||||
Child = colouredDrawable = drawableText;
|
||||
}
|
||||
else
|
||||
{
|
||||
AccentColour = Color4Extensions.FromHex(user.Colour);
|
||||
|
||||
Child = new Container
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
CornerRadius = 4,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Roundness = 1,
|
||||
Radius = 1,
|
||||
Colour = Color4.Black.Opacity(0.3f),
|
||||
Offset = new Vector2(0, 1),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
},
|
||||
Child = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
CornerRadius = 4,
|
||||
Children = new[]
|
||||
{
|
||||
colouredDrawable = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 },
|
||||
Child = drawableText,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
drawableText.Colour = colours.ChatBlue;
|
||||
colouredDrawable.Colour = AccentColour;
|
||||
}
|
||||
|
||||
public MenuItem[] ContextMenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
if (user.Equals(APIUser.SYSTEM_USER))
|
||||
return Array.Empty<MenuItem>();
|
||||
|
||||
List<MenuItem> items = new List<MenuItem>
|
||||
{
|
||||
new OsuMenuItem("View Profile", MenuItemType.Highlighted, openUserProfile)
|
||||
};
|
||||
|
||||
if (!user.Equals(api.LocalUser.Value))
|
||||
items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, openUserChannel));
|
||||
|
||||
return items.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void openUserChannel()
|
||||
{
|
||||
chatManager?.OpenPrivateChannel(user);
|
||||
chatOverlay?.Show();
|
||||
}
|
||||
|
||||
private void openUserProfile()
|
||||
{
|
||||
profileOverlay?.ShowUser(user);
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
colouredDrawable.FadeColour(AccentColour.Lighten(0.6f), 30, Easing.OutQuint);
|
||||
|
||||
return base.OnHover(e);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
base.OnHoverLost(e);
|
||||
|
||||
colouredDrawable.FadeColour(AccentColour, 800, Easing.OutQuint);
|
||||
}
|
||||
|
||||
private static readonly Color4[] default_colours =
|
||||
{
|
||||
Color4Extensions.FromHex("588c7e"),
|
||||
Color4Extensions.FromHex("b2a367"),
|
||||
Color4Extensions.FromHex("c98f65"),
|
||||
Color4Extensions.FromHex("bc5151"),
|
||||
Color4Extensions.FromHex("5c8bd6"),
|
||||
Color4Extensions.FromHex("7f6ab7"),
|
||||
Color4Extensions.FromHex("a368ad"),
|
||||
Color4Extensions.FromHex("aa6880"),
|
||||
|
||||
Color4Extensions.FromHex("6fad9b"),
|
||||
Color4Extensions.FromHex("f2e394"),
|
||||
Color4Extensions.FromHex("f2ae72"),
|
||||
Color4Extensions.FromHex("f98f8a"),
|
||||
Color4Extensions.FromHex("7daef4"),
|
||||
Color4Extensions.FromHex("a691f2"),
|
||||
Color4Extensions.FromHex("c894d3"),
|
||||
Color4Extensions.FromHex("d895b0"),
|
||||
|
||||
Color4Extensions.FromHex("53c4a1"),
|
||||
Color4Extensions.FromHex("eace5c"),
|
||||
Color4Extensions.FromHex("ea8c47"),
|
||||
Color4Extensions.FromHex("fc4f4f"),
|
||||
Color4Extensions.FromHex("3d94ea"),
|
||||
Color4Extensions.FromHex("7760ea"),
|
||||
Color4Extensions.FromHex("af52c6"),
|
||||
Color4Extensions.FromHex("e25696"),
|
||||
|
||||
Color4Extensions.FromHex("677c66"),
|
||||
Color4Extensions.FromHex("9b8732"),
|
||||
Color4Extensions.FromHex("8c5129"),
|
||||
Color4Extensions.FromHex("8c3030"),
|
||||
Color4Extensions.FromHex("1f5d91"),
|
||||
Color4Extensions.FromHex("4335a5"),
|
||||
Color4Extensions.FromHex("812a96"),
|
||||
Color4Extensions.FromHex("992861"),
|
||||
};
|
||||
}
|
||||
}
|
@ -331,11 +331,11 @@ namespace osu.Game.Overlays.Comments
|
||||
if (WasDeleted)
|
||||
makeDeleted();
|
||||
|
||||
actionsContainer.AddLink("Copy link", copyUrl);
|
||||
actionsContainer.AddLink(CommonStrings.ButtonsPermalink, copyUrl);
|
||||
actionsContainer.AddArbitraryDrawable(Empty().With(d => d.Width = 10));
|
||||
|
||||
if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id)
|
||||
actionsContainer.AddLink("Delete", deleteComment);
|
||||
actionsContainer.AddLink(CommonStrings.ButtonsDelete, deleteComment);
|
||||
else
|
||||
actionsContainer.AddArbitraryDrawable(new CommentReportButton(Comment));
|
||||
|
||||
@ -553,12 +553,12 @@ namespace osu.Game.Overlays.Comments
|
||||
};
|
||||
}
|
||||
|
||||
private string getParentMessage()
|
||||
private LocalisableString getParentMessage()
|
||||
{
|
||||
if (parentComment == null)
|
||||
return string.Empty;
|
||||
|
||||
return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? "deleted" : string.Empty;
|
||||
return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? CommentsStrings.Deleted : string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ namespace osu.Game.Overlays.FirstRunSetup
|
||||
return parentDependencies.Get(type, info);
|
||||
}
|
||||
|
||||
public void Inject<T>(T instance) where T : class
|
||||
public void Inject<T>(T instance) where T : class, IDependencyInjectionCandidate
|
||||
{
|
||||
parentDependencies.Inject(instance);
|
||||
}
|
||||
|
@ -177,13 +177,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
updateScreenModeWarning();
|
||||
}, true);
|
||||
|
||||
windowModes.BindCollectionChanged((_, _) =>
|
||||
{
|
||||
if (windowModes.Count > 1)
|
||||
windowModeDropdown.Show();
|
||||
else
|
||||
windowModeDropdown.Hide();
|
||||
}, true);
|
||||
windowModes.BindCollectionChanged((_, _) => updateDisplaySettingsVisibility());
|
||||
|
||||
currentDisplay.BindValueChanged(display => Schedule(() =>
|
||||
{
|
||||
@ -219,7 +213,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
scalingSettings.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
|
||||
|
||||
scalingSettings.AutoSizeAxes = scalingMode.Value != ScalingMode.Off ? Axes.Y : Axes.None;
|
||||
scalingSettings.ForEach(s => s.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything);
|
||||
scalingSettings.ForEach(s =>
|
||||
{
|
||||
s.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything;
|
||||
s.CanBeShown.Value = scalingMode.Value != ScalingMode.Off;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,20 +232,10 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
|
||||
private void updateDisplaySettingsVisibility()
|
||||
{
|
||||
if (resolutions.Count > 1 && windowModeDropdown.Current.Value == WindowMode.Fullscreen)
|
||||
resolutionDropdown.Show();
|
||||
else
|
||||
resolutionDropdown.Hide();
|
||||
|
||||
if (displayDropdown.Items.Count() > 1)
|
||||
displayDropdown.Show();
|
||||
else
|
||||
displayDropdown.Hide();
|
||||
|
||||
if (host.Window?.SafeAreaPadding.Value.Total != Vector2.Zero)
|
||||
safeAreaConsiderationsCheckbox.Show();
|
||||
else
|
||||
safeAreaConsiderationsCheckbox.Hide();
|
||||
windowModeDropdown.CanBeShown.Value = windowModes.Count > 1;
|
||||
resolutionDropdown.CanBeShown.Value = resolutions.Count > 1 && windowModeDropdown.Current.Value == WindowMode.Fullscreen;
|
||||
displayDropdown.CanBeShown.Value = displayDropdown.Items.Count() > 1;
|
||||
safeAreaConsiderationsCheckbox.CanBeShown.Value = host.Window?.SafeAreaPadding.Value.Total != Vector2.Zero;
|
||||
}
|
||||
|
||||
private void updateScreenModeWarning()
|
||||
|
@ -143,6 +143,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
||||
areaOffset.SetDefault();
|
||||
areaSize.SetDefault();
|
||||
},
|
||||
CanBeShown = { BindTarget = enabled }
|
||||
},
|
||||
new SettingsButton
|
||||
{
|
||||
@ -150,25 +151,29 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
||||
Action = () =>
|
||||
{
|
||||
forceAspectRatio((float)host.Window.ClientSize.Width / host.Window.ClientSize.Height);
|
||||
}
|
||||
},
|
||||
CanBeShown = { BindTarget = enabled }
|
||||
},
|
||||
new SettingsSlider<float>
|
||||
{
|
||||
TransferValueOnCommit = true,
|
||||
LabelText = TabletSettingsStrings.XOffset,
|
||||
Current = offsetX
|
||||
Current = offsetX,
|
||||
CanBeShown = { BindTarget = enabled }
|
||||
},
|
||||
new SettingsSlider<float>
|
||||
{
|
||||
TransferValueOnCommit = true,
|
||||
LabelText = TabletSettingsStrings.YOffset,
|
||||
Current = offsetY
|
||||
Current = offsetY,
|
||||
CanBeShown = { BindTarget = enabled }
|
||||
},
|
||||
new SettingsSlider<float>
|
||||
{
|
||||
TransferValueOnCommit = true,
|
||||
LabelText = TabletSettingsStrings.Rotation,
|
||||
Current = rotation
|
||||
Current = rotation,
|
||||
CanBeShown = { BindTarget = enabled }
|
||||
},
|
||||
new RotationPresetButtons(tabletHandler)
|
||||
{
|
||||
@ -181,24 +186,28 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
||||
{
|
||||
TransferValueOnCommit = true,
|
||||
LabelText = TabletSettingsStrings.AspectRatio,
|
||||
Current = aspectRatio
|
||||
Current = aspectRatio,
|
||||
CanBeShown = { BindTarget = enabled }
|
||||
},
|
||||
new SettingsCheckbox
|
||||
{
|
||||
LabelText = TabletSettingsStrings.LockAspectRatio,
|
||||
Current = aspectLock
|
||||
Current = aspectLock,
|
||||
CanBeShown = { BindTarget = enabled }
|
||||
},
|
||||
new SettingsSlider<float>
|
||||
{
|
||||
TransferValueOnCommit = true,
|
||||
LabelText = CommonStrings.Width,
|
||||
Current = sizeX
|
||||
Current = sizeX,
|
||||
CanBeShown = { BindTarget = enabled }
|
||||
},
|
||||
new SettingsSlider<float>
|
||||
{
|
||||
TransferValueOnCommit = true,
|
||||
LabelText = CommonStrings.Height,
|
||||
Current = sizeY
|
||||
Current = sizeY,
|
||||
CanBeShown = { BindTarget = enabled }
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -3,14 +3,16 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics.UserInterfaceV2;
|
||||
|
||||
namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
public partial class SettingsButton : RoundedButton, IHasTooltip
|
||||
public partial class SettingsButton : RoundedButton, IHasTooltip, IConditionalFilterable
|
||||
{
|
||||
public SettingsButton()
|
||||
{
|
||||
@ -20,6 +22,9 @@ namespace osu.Game.Overlays.Settings
|
||||
|
||||
public LocalisableString TooltipText { get; set; }
|
||||
|
||||
public BindableBool CanBeShown { get; } = new BindableBool(true);
|
||||
IBindable<bool> IConditionalFilterable.CanBeShown => CanBeShown;
|
||||
|
||||
public override IEnumerable<LocalisableString> FilterTerms
|
||||
{
|
||||
get
|
||||
|
@ -22,7 +22,7 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
public abstract partial class SettingsItem<T> : Container, IFilterable, ISettingsItem, IHasCurrentValue<T>, IHasTooltip
|
||||
public abstract partial class SettingsItem<T> : Container, IConditionalFilterable, ISettingsItem, IHasCurrentValue<T>, IHasTooltip
|
||||
{
|
||||
protected abstract Drawable CreateControl();
|
||||
|
||||
@ -144,6 +144,9 @@ namespace osu.Game.Overlays.Settings
|
||||
|
||||
public bool FilteringActive { get; set; }
|
||||
|
||||
public BindableBool CanBeShown { get; } = new BindableBool(true);
|
||||
IBindable<bool> IConditionalFilterable.CanBeShown => CanBeShown;
|
||||
|
||||
public event Action SettingChanged;
|
||||
|
||||
private T classicDefault;
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
@ -19,7 +18,7 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
public abstract partial class SettingsSection : Container, IHasFilterableChildren
|
||||
public abstract partial class SettingsSection : Container, IFilterable
|
||||
{
|
||||
protected FillFlowContainer FlowContent;
|
||||
protected override Container<Drawable> Content => FlowContent;
|
||||
@ -33,7 +32,6 @@ namespace osu.Game.Overlays.Settings
|
||||
public abstract Drawable CreateIcon();
|
||||
public abstract LocalisableString Header { get; }
|
||||
|
||||
public IEnumerable<IFilterable> FilterableChildren => Children.OfType<IFilterable>();
|
||||
public virtual IEnumerable<LocalisableString> FilterTerms => new[] { Header };
|
||||
|
||||
public const int ITEM_SPACING = 14;
|
||||
|
@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Testing;
|
||||
@ -17,7 +16,7 @@ using osu.Game.Graphics;
|
||||
namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
[ExcludeFromDynamicCompile]
|
||||
public abstract partial class SettingsSubsection : FillFlowContainer, IHasFilterableChildren
|
||||
public abstract partial class SettingsSubsection : FillFlowContainer, IFilterable
|
||||
{
|
||||
protected override Container<Drawable> Content => FlowContent;
|
||||
|
||||
@ -25,8 +24,6 @@ namespace osu.Game.Overlays.Settings
|
||||
|
||||
protected abstract LocalisableString Header { get; }
|
||||
|
||||
public IEnumerable<IFilterable> FilterableChildren => Children.OfType<IFilterable>();
|
||||
|
||||
public virtual IEnumerable<LocalisableString> FilterTerms => new[] { Header };
|
||||
|
||||
public bool MatchingFilter
|
||||
|
@ -1,8 +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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.LocalisationExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
@ -20,6 +19,8 @@ namespace osu.Game.Screens.Edit
|
||||
{
|
||||
public abstract partial class EditorTable : TableContainer
|
||||
{
|
||||
public event Action<Drawable>? OnRowSelected;
|
||||
|
||||
private const float horizontal_inset = 20;
|
||||
|
||||
protected const float ROW_HEIGHT = 25;
|
||||
@ -45,7 +46,18 @@ namespace osu.Game.Screens.Edit
|
||||
});
|
||||
}
|
||||
|
||||
protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? default);
|
||||
protected void SetSelectedRow(object? item)
|
||||
{
|
||||
foreach (var b in BackgroundFlow)
|
||||
{
|
||||
b.Selected = ReferenceEquals(b.Item, item);
|
||||
|
||||
if (b.Selected)
|
||||
OnRowSelected?.Invoke(b);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Drawable CreateHeader(int index, TableColumn? column) => new HeaderText(column?.Header ?? default);
|
||||
|
||||
private partial class HeaderText : OsuSpriteText
|
||||
{
|
||||
@ -84,11 +96,6 @@ namespace osu.Game.Screens.Edit
|
||||
Alpha = 0,
|
||||
},
|
||||
};
|
||||
|
||||
// todo delete
|
||||
Action = () =>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
private Color4 colourHover;
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -23,10 +21,10 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
public partial class ControlPointTable : EditorTable
|
||||
{
|
||||
[Resolved]
|
||||
private Bindable<ControlPointGroup> selectedGroup { get; set; }
|
||||
private Bindable<ControlPointGroup> selectedGroup { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private EditorClock clock { get; set; }
|
||||
private EditorClock clock { get; set; } = null!;
|
||||
|
||||
public const float TIMING_COLUMN_WIDTH = 230;
|
||||
|
||||
@ -37,7 +35,7 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
Content = null;
|
||||
BackgroundFlow.Clear();
|
||||
|
||||
if (value?.Any() != true)
|
||||
if (!value.Any())
|
||||
return;
|
||||
|
||||
foreach (var group in value)
|
||||
@ -63,19 +61,10 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
selectedGroup.BindValueChanged(_ =>
|
||||
{
|
||||
// TODO: This should scroll the selected row into view.
|
||||
updateSelectedGroup();
|
||||
}, true);
|
||||
selectedGroup.BindValueChanged(_ => updateSelectedGroup(), true);
|
||||
}
|
||||
|
||||
private void updateSelectedGroup()
|
||||
{
|
||||
// TODO: This should scroll the selected row into view.
|
||||
foreach (var b in BackgroundFlow)
|
||||
b.Selected = ReferenceEquals(b.Item, selectedGroup?.Value);
|
||||
}
|
||||
private void updateSelectedGroup() => SetSelectedRow(selectedGroup.Value);
|
||||
|
||||
private TableColumn[] createHeaders()
|
||||
{
|
||||
@ -92,32 +81,38 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
{
|
||||
return new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = TIMING_COLUMN_WIDTH,
|
||||
Spacing = new Vector2(5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = group.Time.ToEditorFormattedString(),
|
||||
Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.Bold),
|
||||
Width = 70,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
new ControlGroupAttributes(group, c => c is TimingControlPoint)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ControlGroupAttributes(group, c => !(c is TimingControlPoint))
|
||||
new ControlGroupTiming(group),
|
||||
new ControlGroupAttributes(group, c => c is not TimingControlPoint)
|
||||
};
|
||||
}
|
||||
|
||||
private partial class ControlGroupTiming : FillFlowContainer
|
||||
{
|
||||
public ControlGroupTiming(ControlPointGroup group)
|
||||
{
|
||||
Name = @"ControlGroupTiming";
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Width = TIMING_COLUMN_WIDTH;
|
||||
Spacing = new Vector2(5);
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = group.Time.ToEditorFormattedString(),
|
||||
Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.Bold),
|
||||
Width = 70,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
new ControlGroupAttributes(group, c => c is TimingControlPoint)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private partial class ControlGroupAttributes : CompositeDrawable
|
||||
{
|
||||
private readonly Func<ControlPoint, bool> matchFunction;
|
||||
@ -132,6 +127,7 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
|
||||
AutoSizeAxes = Axes.X;
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Name = @"ControlGroupAttributes";
|
||||
|
||||
InternalChild = fill = new FillFlowContainer
|
||||
{
|
||||
@ -161,7 +157,6 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
fill.ChildrenEnumerable = controlPoints
|
||||
.Where(matchFunction)
|
||||
.Select(createAttribute)
|
||||
.Where(c => c != null)
|
||||
// arbitrary ordering to make timing points first.
|
||||
// probably want to explicitly define order in the future.
|
||||
.OrderByDescending(c => c.GetType().Name);
|
||||
@ -184,7 +179,7 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
return new SampleRowAttribute(sample);
|
||||
}
|
||||
|
||||
return null;
|
||||
throw new ArgumentOutOfRangeException(nameof(controlPoint), $"Control point type {controlPoint.GetType()} is not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
@ -50,24 +48,24 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
|
||||
public partial class ControlPointList : CompositeDrawable
|
||||
{
|
||||
private OsuButton deleteButton;
|
||||
private ControlPointTable table;
|
||||
private OsuButton deleteButton = null!;
|
||||
private ControlPointTable table = null!;
|
||||
private OsuScrollContainer scroll = null!;
|
||||
private RoundedButton addButton = null!;
|
||||
|
||||
private readonly IBindableList<ControlPointGroup> controlPointGroups = new BindableList<ControlPointGroup>();
|
||||
|
||||
private RoundedButton addButton;
|
||||
[Resolved]
|
||||
private EditorClock clock { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private EditorClock clock { get; set; }
|
||||
protected EditorBeatmap Beatmap { get; private set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
protected EditorBeatmap Beatmap { get; private set; }
|
||||
private Bindable<ControlPointGroup?> selectedGroup { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private Bindable<ControlPointGroup> selectedGroup { get; set; }
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private IEditorChangeHandler changeHandler { get; set; }
|
||||
private IEditorChangeHandler? changeHandler { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colours)
|
||||
@ -88,7 +86,7 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = ControlPointTable.TIMING_COLUMN_WIDTH + margins,
|
||||
},
|
||||
new OsuScrollContainer
|
||||
scroll = new OsuScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = table = new ControlPointTable(),
|
||||
@ -142,6 +140,8 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
table.ControlGroups = controlPointGroups;
|
||||
changeHandler?.SaveState();
|
||||
}, true);
|
||||
|
||||
table.OnRowSelected += drawable => scroll.ScrollIntoView(drawable);
|
||||
}
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
@ -159,7 +159,7 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
addButton.Enabled.Value = clock.CurrentTimeAccurate != selectedGroup.Value?.Time;
|
||||
}
|
||||
|
||||
private Type trackedType;
|
||||
private Type? trackedType;
|
||||
|
||||
/// <summary>
|
||||
/// Given the user has selected a control point group, we want to track any group which is
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
@ -20,19 +18,19 @@ namespace osu.Game.Screens.Edit.Verify
|
||||
{
|
||||
public partial class IssueTable : EditorTable
|
||||
{
|
||||
[Resolved]
|
||||
private VerifyScreen verify { get; set; }
|
||||
|
||||
private Bindable<Issue> selectedIssue;
|
||||
private Bindable<Issue> selectedIssue = null!;
|
||||
|
||||
[Resolved]
|
||||
private EditorClock clock { get; set; }
|
||||
private VerifyScreen verify { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private EditorBeatmap editorBeatmap { get; set; }
|
||||
private EditorClock clock { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private Editor editor { get; set; }
|
||||
private EditorBeatmap editorBeatmap { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private Editor editor { get; set; } = null!;
|
||||
|
||||
public IEnumerable<Issue> Issues
|
||||
{
|
||||
@ -41,7 +39,7 @@ namespace osu.Game.Screens.Edit.Verify
|
||||
Content = null;
|
||||
BackgroundFlow.Clear();
|
||||
|
||||
if (value == null)
|
||||
if (!value.Any())
|
||||
return;
|
||||
|
||||
foreach (var issue in value)
|
||||
@ -79,7 +77,7 @@ namespace osu.Game.Screens.Edit.Verify
|
||||
selectedIssue = verify.SelectedIssue.GetBoundCopy();
|
||||
selectedIssue.BindValueChanged(issue =>
|
||||
{
|
||||
foreach (var b in BackgroundFlow) b.Selected = b.Item == issue.NewValue;
|
||||
SetSelectedRow(issue.NewValue);
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
@ -1,152 +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.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Localisation;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Select
|
||||
{
|
||||
internal partial class DifficultyRangeFilterControl : CompositeDrawable
|
||||
{
|
||||
private Bindable<double> lowerStars = null!;
|
||||
private Bindable<double> upperStars = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
const float vertical_offset = 13;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "Difficulty range",
|
||||
Font = OsuFont.GetFont(size: 14),
|
||||
},
|
||||
new MaximumStarsSlider
|
||||
{
|
||||
Current = config.GetBindable<double>(OsuSetting.DisplayStarsMaximum),
|
||||
KeyboardStep = 0.1f,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Y = vertical_offset,
|
||||
},
|
||||
new MinimumStarsSlider
|
||||
{
|
||||
Current = config.GetBindable<double>(OsuSetting.DisplayStarsMinimum),
|
||||
KeyboardStep = 0.1f,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Y = vertical_offset,
|
||||
}
|
||||
};
|
||||
|
||||
lowerStars = config.GetBindable<double>(OsuSetting.DisplayStarsMinimum);
|
||||
upperStars = config.GetBindable<double>(OsuSetting.DisplayStarsMaximum);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
lowerStars.ValueChanged += min => upperStars.Value = Math.Max(min.NewValue + 0.1, upperStars.Value);
|
||||
upperStars.ValueChanged += max => lowerStars.Value = Math.Min(max.NewValue - 0.1, lowerStars.Value);
|
||||
}
|
||||
|
||||
private partial class MinimumStarsSlider : StarsSlider
|
||||
{
|
||||
public MinimumStarsSlider()
|
||||
: base("0")
|
||||
{
|
||||
}
|
||||
|
||||
public override LocalisableString TooltipText => Current.Value.ToString(@"0.## stars");
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
LeftBox.Height = 6; // hide any colour bleeding from overlap
|
||||
|
||||
AccentColour = BackgroundColour;
|
||||
BackgroundColour = Color4.Transparent;
|
||||
}
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
|
||||
base.ReceivePositionalInputAt(screenSpacePos)
|
||||
&& screenSpacePos.X <= Nub.ScreenSpaceDrawQuad.TopRight.X;
|
||||
}
|
||||
|
||||
private partial class MaximumStarsSlider : StarsSlider
|
||||
{
|
||||
public MaximumStarsSlider()
|
||||
: base("∞")
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
RightBox.Height = 6; // just to match the left bar height really
|
||||
}
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
|
||||
base.ReceivePositionalInputAt(screenSpacePos)
|
||||
&& screenSpacePos.X >= Nub.ScreenSpaceDrawQuad.TopLeft.X;
|
||||
}
|
||||
|
||||
private partial class StarsSlider : OsuSliderBar<double>
|
||||
{
|
||||
private readonly string defaultString;
|
||||
|
||||
public override LocalisableString TooltipText => Current.IsDefault
|
||||
? UserInterfaceStrings.NoLimit
|
||||
: Current.Value.ToString(@"0.## stars");
|
||||
|
||||
protected StarsSlider(string defaultString)
|
||||
{
|
||||
this.defaultString = defaultString;
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
base.OnHover(e);
|
||||
return true; // Make sure only one nub shows hover effect at once.
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
Nub.Width = Nub.HEIGHT;
|
||||
RangePadding = Nub.Width / 2;
|
||||
|
||||
OsuSpriteText currentDisplay;
|
||||
|
||||
Nub.Add(currentDisplay = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Y = -0.5f,
|
||||
Colour = Color4.White,
|
||||
Font = OsuFont.Torus.With(size: 10),
|
||||
});
|
||||
|
||||
Current.BindValueChanged(current =>
|
||||
{
|
||||
currentDisplay.Text = current.NewValue != Current.Default ? current.NewValue.ToString("N1") : defaultString;
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Select.Filter;
|
||||
@ -172,12 +173,19 @@ namespace osu.Game.Screens.Select
|
||||
Height = 40,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DifficultyRangeFilterControl
|
||||
new RangeSlider
|
||||
{
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
Label = "Difficulty range",
|
||||
LowerBound = config.GetBindable<double>(OsuSetting.DisplayStarsMinimum),
|
||||
UpperBound = config.GetBindable<double>(OsuSetting.DisplayStarsMaximum),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.48f,
|
||||
DefaultStringLowerBound = "0",
|
||||
DefaultStringUpperBound = "∞",
|
||||
DefaultTooltipUpperBound = UserInterfaceStrings.NoLimit,
|
||||
TooltipSuffix = "stars"
|
||||
},
|
||||
collectionDropdown = new CollectionDropdown
|
||||
{
|
||||
|
@ -164,7 +164,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
return fallback.Get(type, info);
|
||||
}
|
||||
|
||||
public void Inject<T>(T instance) where T : class
|
||||
public void Inject<T>(T instance) where T : class, IDependencyInjectionCandidate
|
||||
{
|
||||
// Never used directly
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Tests
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
await API.PerformAsync(CreateFetchMessagesRequest());
|
||||
await API.PerformAsync(CreateInitialFetchRequest());
|
||||
await Task.Delay(1000, cancellationToken);
|
||||
}
|
||||
}, cancellationToken);
|
||||
|
@ -128,7 +128,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay
|
||||
=> OnlinePlayDependencies?.Get(type, info) ?? parent.Get(type, info);
|
||||
|
||||
public void Inject<T>(T instance)
|
||||
where T : class
|
||||
where T : class, IDependencyInjectionCandidate
|
||||
=> injectableDependencies.Inject(instance);
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay
|
||||
=> dependencies.Get(type, info);
|
||||
|
||||
public void Inject<T>(T instance)
|
||||
where T : class
|
||||
where T : class, IDependencyInjectionCandidate
|
||||
=> dependencies.Inject(instance);
|
||||
|
||||
protected void Cache(object instance)
|
||||
|
@ -35,7 +35,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Realm" Version="10.18.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2022.1126.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2022.1130.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.1127.0" />
|
||||
<PackageReference Include="Sentry" Version="3.23.1" />
|
||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||
|
@ -62,7 +62,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.1127.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.1126.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.1130.0" />
|
||||
</ItemGroup>
|
||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
|
||||
<PropertyGroup>
|
||||
@ -82,7 +82,7 @@
|
||||
<PackageReference Include="DiffPlex" Version="1.7.1" />
|
||||
<PackageReference Include="Humanizer" Version="2.14.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2022.1126.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2022.1130.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
|
Loading…
Reference in New Issue
Block a user