1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-19 11:32:54 +08:00

Merge branch 'master' into editor-key-count

This commit is contained in:
Bartłomiej Dach 2023-07-22 16:11:21 +02:00
commit d1c69283b2
No known key found for this signature in database
33 changed files with 341 additions and 236 deletions

View File

@ -62,12 +62,7 @@ namespace osu.Game.Rulesets.Osu.Edit
private void load() private void load()
{ {
// Give a bit of breathing room around the playfield content. // Give a bit of breathing room around the playfield content.
PlayfieldContentContainer.Padding = new MarginPadding PlayfieldContentContainer.Padding = new MarginPadding(10);
{
Vertical = 10,
Left = TOOLBOX_CONTRACTED_SIZE_LEFT + 10,
Right = TOOLBOX_CONTRACTED_SIZE_RIGHT + 10,
};
LayerBelowRuleset.AddRange(new Drawable[] LayerBelowRuleset.AddRange(new Drawable[]
{ {

View File

@ -22,7 +22,6 @@ namespace osu.Game.Tests.Visual.Editing
public partial class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene public partial class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene
{ {
private BeatDivisorControl beatDivisorControl = null!; private BeatDivisorControl beatDivisorControl = null!;
private BindableBeatDivisor bindableBeatDivisor = null!;
private SliderBar<int> tickSliderBar => beatDivisorControl.ChildrenOfType<SliderBar<int>>().Single(); private SliderBar<int> tickSliderBar => beatDivisorControl.ChildrenOfType<SliderBar<int>>().Single();
private Triangle tickMarkerHead => tickSliderBar.ChildrenOfType<Triangle>().Single(); private Triangle tickMarkerHead => tickSliderBar.ChildrenOfType<Triangle>().Single();
@ -30,13 +29,19 @@ namespace osu.Game.Tests.Visual.Editing
[Cached] [Cached]
private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Aquamarine); private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Aquamarine);
[Cached]
private readonly BindableBeatDivisor bindableBeatDivisor = new BindableBeatDivisor(16);
[SetUp] [SetUp]
public void SetUp() => Schedule(() => public void SetUp() => Schedule(() =>
{ {
bindableBeatDivisor.ValidDivisors.SetDefault();
bindableBeatDivisor.SetDefault();
Child = new PopoverContainer Child = new PopoverContainer
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Child = beatDivisorControl = new BeatDivisorControl(bindableBeatDivisor = new BindableBeatDivisor(16)) Child = beatDivisorControl = new BeatDivisorControl
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,

View File

@ -117,9 +117,9 @@ namespace osu.Game.Tests.Visual.Editing
AddStep("move mouse to overlapping toggle button", () => AddStep("move mouse to overlapping toggle button", () =>
{ {
var playfield = hitObjectComposer.Playfield.ScreenSpaceDrawQuad; var playfield = hitObjectComposer.Playfield.ScreenSpaceDrawQuad;
var button = toolboxContainer.ChildrenOfType<DrawableTernaryButton>().First(b => playfield.Contains(b.ScreenSpaceDrawQuad.Centre)); var button = toolboxContainer.ChildrenOfType<DrawableTernaryButton>().First(b => playfield.Contains(getOverlapPoint(b)));
InputManager.MoveMouseTo(button); InputManager.MoveMouseTo(getOverlapPoint(button));
}); });
AddAssert("no circles placed", () => editorBeatmap.HitObjects.Count == 0); AddAssert("no circles placed", () => editorBeatmap.HitObjects.Count == 0);
@ -127,6 +127,12 @@ namespace osu.Game.Tests.Visual.Editing
AddStep("attempt place circle", () => InputManager.Click(MouseButton.Left)); AddStep("attempt place circle", () => InputManager.Click(MouseButton.Left));
AddAssert("no circles placed", () => editorBeatmap.HitObjects.Count == 0); AddAssert("no circles placed", () => editorBeatmap.HitObjects.Count == 0);
Vector2 getOverlapPoint(DrawableTernaryButton ternaryButton)
{
var quad = ternaryButton.ScreenSpaceDrawQuad;
return quad.TopLeft + new Vector2(quad.Width * 9 / 10, quad.Height / 2);
}
} }
[Test] [Test]

View File

@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Editing
{ {
BeatDivisor.Value = 4; BeatDivisor.Value = 4;
Add(new BeatDivisorControl(BeatDivisor) Add(new BeatDivisorControl
{ {
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,

View File

@ -12,7 +12,7 @@ namespace osu.Game.Tournament.Tests
[STAThread] [STAThread]
public static int Main(string[] args) public static int Main(string[] args)
{ {
using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu", new HostOptions { BindIPC = true })) using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu-development", new HostOptions { BindIPC = true }))
{ {
host.Run(new TournamentTestBrowser()); host.Run(new TournamentTestBrowser());
return 0; return 0;

View File

@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Platform; using osu.Framework.Platform;
@ -43,6 +45,6 @@ namespace osu.Game.Tournament.IO
Logger.Log("Changing tournament storage: " + GetFullPath(string.Empty)); Logger.Log("Changing tournament storage: " + GetFullPath(string.Empty));
} }
public IEnumerable<string> ListTournaments() => AllTournaments.GetDirectories(string.Empty); public IEnumerable<string> ListTournaments() => AllTournaments.GetDirectories(string.Empty).OrderBy(directory => directory, StringComparer.CurrentCultureIgnoreCase);
} }
} }

View File

@ -25,12 +25,11 @@ namespace osu.Game.Tournament
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
InternalChild = new Container InternalChild = new CircularContainer
{ {
Anchor = Anchor.BottomRight, Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight, Origin = Anchor.BottomRight,
Position = new Vector2(5), Position = new Vector2(-5),
CornerRadius = 10,
Masking = true, Masking = true,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
@ -43,18 +42,10 @@ namespace osu.Game.Tournament
saveChangesButton = new TourneyButton saveChangesButton = new TourneyButton
{ {
Text = "Save Changes", Text = "Save Changes",
RelativeSizeAxes = Axes.None,
Width = 140, Width = 140,
Height = 50, Height = 50,
Padding = new MarginPadding Margin = new MarginPadding(10),
{
Top = 10,
Left = 10,
},
Margin = new MarginPadding
{
Right = 10,
Bottom = 10,
},
Action = saveChanges, Action = saveChanges,
// Enabled = { Value = false }, // Enabled = { Value = false },
}, },

View File

@ -11,10 +11,9 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Online.API;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models; using osu.Game.Tournament.Models;
using osu.Game.Tournament.Screens.Drawings.Components;
using osu.Game.Users; using osu.Game.Users;
using osuTK; using osuTK;
@ -59,8 +58,6 @@ namespace osu.Game.Tournament.Screens.Editors
{ {
public TournamentTeam Model { get; } public TournamentTeam Model { get; }
private readonly Container drawableContainer;
[Resolved] [Resolved]
private TournamentSceneManager? sceneManager { get; set; } private TournamentSceneManager? sceneManager { get; set; }
@ -74,10 +71,10 @@ namespace osu.Game.Tournament.Screens.Editors
Masking = true; Masking = true;
CornerRadius = 10; CornerRadius = 10;
PlayerEditor playerEditor = new PlayerEditor(Model) RelativeSizeAxes = Axes.X;
{ AutoSizeAxes = Axes.Y;
Width = 0.95f
}; PlayerEditor playerEditor = new PlayerEditor(Model);
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
@ -86,17 +83,17 @@ namespace osu.Game.Tournament.Screens.Editors
Colour = OsuColour.Gray(0.1f), Colour = OsuColour.Gray(0.1f),
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
drawableContainer = new Container new GroupTeam(team)
{ {
Size = new Vector2(100, 50), Margin = new MarginPadding(16),
Margin = new MarginPadding(10), Scale = new Vector2(2),
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
}, },
new FillFlowContainer new FillFlowContainer
{ {
Margin = new MarginPadding(5),
Spacing = new Vector2(5), Spacing = new Vector2(5),
Padding = new MarginPadding(10),
Direction = FillDirection.Full, Direction = FillDirection.Full,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
@ -133,25 +130,6 @@ namespace osu.Game.Tournament.Screens.Editors
Current = Model.LastYearPlacing Current = Model.LastYearPlacing
}, },
new SettingsButton new SettingsButton
{
Width = 0.11f,
Margin = new MarginPadding(10),
Text = "Add player",
Action = () => playerEditor.CreateNew()
},
new DangerousSettingsButton
{
Width = 0.11f,
Text = "Delete Team",
Margin = new MarginPadding(10),
Action = () =>
{
Expire();
ladderInfo.Teams.Remove(Model);
},
},
playerEditor,
new SettingsButton
{ {
Width = 0.2f, Width = 0.2f,
Margin = new MarginPadding(10), Margin = new MarginPadding(10),
@ -161,19 +139,35 @@ namespace osu.Game.Tournament.Screens.Editors
sceneManager?.SetScreen(new SeedingEditorScreen(team, parent)); sceneManager?.SetScreen(new SeedingEditorScreen(team, parent));
} }
}, },
playerEditor,
new SettingsButton
{
Text = "Add player",
Action = () => playerEditor.CreateNew()
},
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
new DangerousSettingsButton
{
Width = 0.2f,
Text = "Delete Team",
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Action = () =>
{
Expire();
ladderInfo.Teams.Remove(Model);
},
},
}
},
} }
}, },
}; };
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Model.FlagName.BindValueChanged(updateDrawable, true);
}
private void updateDrawable(ValueChangedEvent<string> flag)
{
drawableContainer.Child = new DrawableTeamFlag(Model);
} }
public partial class PlayerEditor : CompositeDrawable public partial class PlayerEditor : CompositeDrawable
@ -193,6 +187,8 @@ namespace osu.Game.Tournament.Screens.Editors
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Padding = new MarginPadding(5),
Spacing = new Vector2(5),
ChildrenEnumerable = team.Players.Select(p => new PlayerRow(team, p)) ChildrenEnumerable = team.Players.Select(p => new PlayerRow(team, p))
}; };
} }
@ -208,27 +204,22 @@ namespace osu.Game.Tournament.Screens.Editors
{ {
private readonly TournamentUser user; private readonly TournamentUser user;
[Resolved]
protected IAPIProvider API { get; private set; } = null!;
[Resolved] [Resolved]
private TournamentGameBase game { get; set; } = null!; private TournamentGameBase game { get; set; } = null!;
private readonly Bindable<int?> playerId = new Bindable<int?>(); private readonly Bindable<int?> playerId = new Bindable<int?>();
private readonly Container drawableContainer; private readonly Container userPanelContainer;
public PlayerRow(TournamentTeam team, TournamentUser user) public PlayerRow(TournamentTeam team, TournamentUser user)
{ {
this.user = user; this.user = user;
Margin = new MarginPadding(10);
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
Masking = true; Masking = true;
CornerRadius = 5; CornerRadius = 10;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
@ -240,10 +231,11 @@ namespace osu.Game.Tournament.Screens.Editors
new FillFlowContainer new FillFlowContainer
{ {
Margin = new MarginPadding(5), Margin = new MarginPadding(5),
Padding = new MarginPadding { Right = 160 }, Padding = new MarginPadding { Right = 60 },
Spacing = new Vector2(5), Spacing = new Vector2(5),
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[] Children = new Drawable[]
{ {
new SettingsNumberBox new SettingsNumberBox
@ -253,9 +245,10 @@ namespace osu.Game.Tournament.Screens.Editors
Width = 200, Width = 200,
Current = playerId, Current = playerId,
}, },
drawableContainer = new Container userPanelContainer = new Container
{ {
Size = new Vector2(100, 70), Width = 400,
RelativeSizeAxes = Axes.Y,
}, },
} }
}, },
@ -298,7 +291,12 @@ namespace osu.Game.Tournament.Screens.Editors
private void updatePanel() => Scheduler.AddOnce(() => private void updatePanel() => Scheduler.AddOnce(() =>
{ {
drawableContainer.Child = new UserGridPanel(user.ToAPIUser()) { Width = 300 }; userPanelContainer.Child = new UserListPanel(user.ToAPIUser())
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Scale = new Vector2(1f),
};
}); });
} }
} }

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -15,7 +13,6 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Overlays.Settings;
using osu.Game.Tournament.Components; using osu.Game.Tournament.Components;
using osuTK; using osuTK;
@ -27,23 +24,24 @@ namespace osu.Game.Tournament.Screens.Editors
{ {
protected abstract BindableList<TModel> Storage { get; } protected abstract BindableList<TModel> Storage { get; }
private FillFlowContainer<TDrawable> flow; private FillFlowContainer<TDrawable> flow = null!;
[Resolved(canBeNull: true)] [Resolved]
private TournamentSceneManager sceneManager { get; set; } private TournamentSceneManager? sceneManager { get; set; }
protected ControlPanel ControlPanel; protected ControlPanel ControlPanel = null!;
private readonly TournamentScreen parentScreen; private readonly TournamentScreen? parentScreen;
private BackButton backButton;
protected TournamentEditorScreen(TournamentScreen parentScreen = null) private BackButton backButton = null!;
protected TournamentEditorScreen(TournamentScreen? parentScreen = null)
{ {
this.parentScreen = parentScreen; this.parentScreen = parentScreen;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load(OsuColour colours)
{ {
AddRangeInternal(new Drawable[] AddRangeInternal(new Drawable[]
{ {
@ -63,6 +61,7 @@ namespace osu.Game.Tournament.Screens.Editors
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Spacing = new Vector2(20), Spacing = new Vector2(20),
Padding = new MarginPadding(20),
}, },
}, },
ControlPanel = new ControlPanel ControlPanel = new ControlPanel
@ -75,9 +74,10 @@ namespace osu.Game.Tournament.Screens.Editors
Text = "Add new", Text = "Add new",
Action = () => Storage.Add(new TModel()) Action = () => Storage.Add(new TModel())
}, },
new DangerousSettingsButton new TourneyButton
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
BackgroundColour = colours.Pink3,
Text = "Clear all", Text = "Clear all",
Action = Storage.Clear Action = Storage.Clear
}, },

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System; using System;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -15,7 +13,15 @@ namespace osu.Game.Tournament.Screens.Setup
{ {
internal partial class ActionableInfo : LabelledDrawable<Drawable> internal partial class ActionableInfo : LabelledDrawable<Drawable>
{ {
protected OsuButton Button; public const float BUTTON_SIZE = 120;
public Action? Action;
protected FillFlowContainer FlowContainer = null!;
protected OsuButton Button = null!;
private TournamentSpriteText valueText = null!;
public ActionableInfo() public ActionableInfo()
: base(true) : base(true)
@ -37,11 +43,6 @@ namespace osu.Game.Tournament.Screens.Setup
set => valueText.Colour = value ? Color4.Red : Color4.White; set => valueText.Colour = value ? Color4.Red : Color4.White;
} }
public Action Action;
private TournamentSpriteText valueText;
protected FillFlowContainer FlowContainer;
protected override Drawable CreateComponent() => new Container protected override Drawable CreateComponent() => new Container
{ {
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
@ -63,7 +64,7 @@ namespace osu.Game.Tournament.Screens.Setup
{ {
Button = new RoundedButton Button = new RoundedButton
{ {
Size = new Vector2(100, 40), Size = new Vector2(BUTTON_SIZE, 40),
Action = () => Action?.Invoke() Action = () => Action?.Invoke()
} }
} }

View File

@ -106,8 +106,8 @@ namespace osu.Game.Tournament.Screens.Setup
loginOverlay.State.Value = Visibility.Visible; loginOverlay.State.Value = Visibility.Visible;
}, },
Value = api?.LocalUser.Value.Username, Value = api.LocalUser.Value.Username,
Failing = api?.IsLoggedIn != true, Failing = api.IsLoggedIn != true,
Description = "In order to access the API and display metadata, signing in is required." Description = "In order to access the API and display metadata, signing in is required."
}, },
new LabelledDropdown<RulesetInfo> new LabelledDropdown<RulesetInfo>

View File

@ -15,6 +15,7 @@ namespace osu.Game.Tournament.Screens.Setup
{ {
private OsuDropdown<string> dropdown; private OsuDropdown<string> dropdown;
private OsuButton folderButton; private OsuButton folderButton;
private OsuButton reloadTournamentsButton;
[Resolved] [Resolved]
private TournamentGameBase game { get; set; } private TournamentGameBase game { get; set; }
@ -28,6 +29,8 @@ namespace osu.Game.Tournament.Screens.Setup
dropdown.Items = storage.ListTournaments(); dropdown.Items = storage.ListTournaments();
dropdown.Current.BindValueChanged(v => Button.Enabled.Value = v.NewValue != startupTournament, true); dropdown.Current.BindValueChanged(v => Button.Enabled.Value = v.NewValue != startupTournament, true);
reloadTournamentsButton.Action = () => dropdown.Items = storage.ListTournaments();
Action = () => Action = () =>
{ {
game.RestartAppWhenExited(); game.RestartAppWhenExited();
@ -45,10 +48,16 @@ namespace osu.Game.Tournament.Screens.Setup
FlowContainer.Insert(-1, folderButton = new RoundedButton FlowContainer.Insert(-1, folderButton = new RoundedButton
{ {
Text = "Open folder", Text = "Open folder",
Width = 100 Width = BUTTON_SIZE
}); });
FlowContainer.Insert(-2, dropdown = new OsuDropdown<string> FlowContainer.Insert(-2, reloadTournamentsButton = new RoundedButton
{
Text = "Refresh",
Width = BUTTON_SIZE
});
FlowContainer.Insert(-3, dropdown = new OsuDropdown<string>
{ {
Width = 510 Width = 510
}); });

View File

@ -252,14 +252,13 @@ namespace osu.Game.Tournament
if (shortcutKey != null) if (shortcutKey != null)
{ {
Add(new Container Add(new CircularContainer
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
Size = new Vector2(24), Size = new Vector2(24),
Margin = new MarginPadding(5), Margin = new MarginPadding(5),
Masking = true, Masking = true,
CornerRadius = 4,
Alpha = 0.5f, Alpha = 0.5f,
Blending = BlendingParameters.Additive, Blending = BlendingParameters.Additive,
Children = new Drawable[] Children = new Drawable[]

View File

@ -1,18 +1,21 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings;
namespace osu.Game.Tournament namespace osu.Game.Tournament
{ {
public partial class TourneyButton : OsuButton public partial class TourneyButton : SettingsButton
{ {
public new Box Background => base.Background; public new Box Background => base.Background;
public TourneyButton() [BackgroundDependencyLoader]
: base(null) private void load()
{ {
Padding = new MarginPadding();
} }
} }
} }

View File

@ -20,16 +20,16 @@ namespace osu.Game.Graphics.UserInterface
{ {
public const float HEIGHT = 15; public const float HEIGHT = 15;
public const float EXPANDED_SIZE = 50; public const float DEFAULT_EXPANDED_SIZE = 50;
private const float border_width = 3; private const float border_width = 3;
private readonly Box fill; private readonly Box fill;
private readonly Container main; private readonly Container main;
public Nub() public Nub(float expandedSize = DEFAULT_EXPANDED_SIZE)
{ {
Size = new Vector2(EXPANDED_SIZE, HEIGHT); Size = new Vector2(expandedSize, HEIGHT);
InternalChildren = new[] InternalChildren = new[]
{ {

View File

@ -47,7 +47,7 @@ namespace osu.Game.Graphics.UserInterface
private Sample sampleChecked; private Sample sampleChecked;
private Sample sampleUnchecked; private Sample sampleUnchecked;
public OsuCheckbox(bool nubOnRight = true) public OsuCheckbox(bool nubOnRight = true, float nubSize = Nub.DEFAULT_EXPANDED_SIZE)
{ {
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
@ -61,7 +61,7 @@ namespace osu.Game.Graphics.UserInterface
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
}, },
Nub = new Nub(), Nub = new Nub(nubSize),
new HoverSounds() new HoverSounds()
}; };
@ -70,14 +70,14 @@ namespace osu.Game.Graphics.UserInterface
Nub.Anchor = Anchor.CentreRight; Nub.Anchor = Anchor.CentreRight;
Nub.Origin = Anchor.CentreRight; Nub.Origin = Anchor.CentreRight;
Nub.Margin = new MarginPadding { Right = nub_padding }; Nub.Margin = new MarginPadding { Right = nub_padding };
LabelTextFlowContainer.Padding = new MarginPadding { Right = Nub.EXPANDED_SIZE + nub_padding * 2 }; LabelTextFlowContainer.Padding = new MarginPadding { Right = Nub.DEFAULT_EXPANDED_SIZE + nub_padding * 2 };
} }
else else
{ {
Nub.Anchor = Anchor.CentreLeft; Nub.Anchor = Anchor.CentreLeft;
Nub.Origin = Anchor.CentreLeft; Nub.Origin = Anchor.CentreLeft;
Nub.Margin = new MarginPadding { Left = nub_padding }; Nub.Margin = new MarginPadding { Left = nub_padding };
LabelTextFlowContainer.Padding = new MarginPadding { Left = Nub.EXPANDED_SIZE + nub_padding * 2 }; LabelTextFlowContainer.Padding = new MarginPadding { Left = Nub.DEFAULT_EXPANDED_SIZE + nub_padding * 2 };
} }
Nub.Current.BindTo(Current); Nub.Current.BindTo(Current);

View File

@ -51,7 +51,7 @@ namespace osu.Game.Graphics.UserInterface
public RoundedSliderBar() public RoundedSliderBar()
{ {
Height = Nub.HEIGHT; Height = Nub.HEIGHT;
RangePadding = Nub.EXPANDED_SIZE / 2; RangePadding = Nub.DEFAULT_EXPANDED_SIZE / 2;
Children = new Drawable[] Children = new Drawable[]
{ {
new Container new Container

View File

@ -196,7 +196,7 @@ namespace osu.Game.Overlays.Settings
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0, 10), Spacing = new Vector2(0, 5),
Child = Control = CreateControl(), Child = Control = CreateControl(),
} }
} }

View File

@ -36,7 +36,6 @@ namespace osu.Game.Overlays.Settings
{ {
numberBox = new OutlinedNumberBox numberBox = new OutlinedNumberBox
{ {
Margin = new MarginPadding { Top = 5 },
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
CommitOnFocusLost = true CommitOnFocusLost = true
} }

View File

@ -117,13 +117,10 @@ namespace osu.Game.Rulesets.Edit
{ {
PlayfieldContentContainer = new Container PlayfieldContentContainer = new Container
{ {
Name = "Content", Name = "Playfield content",
Padding = new MarginPadding RelativeSizeAxes = Axes.Y,
{ Anchor = Anchor.Centre,
Left = TOOLBOX_CONTRACTED_SIZE_LEFT, Origin = Anchor.Centre,
Right = TOOLBOX_CONTRACTED_SIZE_RIGHT,
},
RelativeSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
// layers below playfield // layers below playfield
@ -240,6 +237,14 @@ namespace osu.Game.Rulesets.Edit
}); });
} }
protected override void Update()
{
base.Update();
// Ensure that the playfield is always centered but also doesn't get cut off by toolboxes.
PlayfieldContentContainer.Width = Math.Max(1024, DrawWidth) - TOOLBOX_CONTRACTED_SIZE_RIGHT * 2;
}
public override Playfield Playfield => drawableRulesetWrapper.Playfield; public override Playfield Playfield => drawableRulesetWrapper.Playfield;
public override IEnumerable<DrawableHitObject> HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects; public override IEnumerable<DrawableHitObject> HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects;
@ -472,7 +477,7 @@ namespace osu.Game.Rulesets.Edit
public abstract partial class HitObjectComposer : CompositeDrawable, IPositionSnapProvider public abstract partial class HitObjectComposer : CompositeDrawable, IPositionSnapProvider
{ {
public const float TOOLBOX_CONTRACTED_SIZE_LEFT = 60; public const float TOOLBOX_CONTRACTED_SIZE_LEFT = 60;
public const float TOOLBOX_CONTRACTED_SIZE_RIGHT = 130; public const float TOOLBOX_CONTRACTED_SIZE_RIGHT = 120;
public readonly Ruleset Ruleset; public readonly Ruleset Ruleset;

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Rulesets.Edit;
using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components;
using osu.Game.Screens.Edit.Components.Timelines.Summary; using osu.Game.Screens.Edit.Components.Timelines.Summary;
using osuTK; using osuTK;
@ -57,7 +58,7 @@ namespace osu.Game.Screens.Edit
new Dimension(GridSizeMode.Absolute, 170), new Dimension(GridSizeMode.Absolute, 170),
new Dimension(), new Dimension(),
new Dimension(GridSizeMode.Absolute, 220), new Dimension(GridSizeMode.Absolute, 220),
new Dimension(GridSizeMode.Absolute, 120), new Dimension(GridSizeMode.Absolute, HitObjectComposer.TOOLBOX_CONTRACTED_SIZE_RIGHT),
}, },
Content = new[] Content = new[]
{ {
@ -69,7 +70,6 @@ namespace osu.Game.Screens.Edit
TestGameplayButton = new TestGameplayButton TestGameplayButton = new TestGameplayButton
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = 10 },
Size = new Vector2(1), Size = new Vector2(1),
Action = editor.TestGameplay, Action = editor.TestGameplay,
} }

View File

@ -3,6 +3,9 @@
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.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -14,19 +17,59 @@ namespace osu.Game.Screens.Edit.Components.Menus
{ {
public partial class EditorMenuBar : OsuMenu public partial class EditorMenuBar : OsuMenu
{ {
private const float heading_area = 114;
public EditorMenuBar() public EditorMenuBar()
: base(Direction.Horizontal, true) : base(Direction.Horizontal, true)
{ {
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
MaskingContainer.CornerRadius = 0; MaskingContainer.CornerRadius = 0;
ItemsContainer.Padding = new MarginPadding { Left = 100 }; ItemsContainer.Padding = new MarginPadding();
ContentContainer.Margin = new MarginPadding { Left = heading_area };
ContentContainer.Masking = true;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider) private void load(OverlayColourProvider colourProvider, TextureStore textures)
{ {
BackgroundColour = colourProvider.Background3; BackgroundColour = colourProvider.Background3;
TextFlowContainer text;
AddRangeInternal(new[]
{
new Container
{
RelativeSizeAxes = Axes.Y,
Width = heading_area,
Padding = new MarginPadding(8),
Children = new Drawable[]
{
new Sprite
{
Size = new Vector2(26),
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Texture = textures.Get("Icons/Hexacons/editor"),
},
text = new TextFlowContainer
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
AutoSizeAxes = Axes.Both,
}
}
},
});
text.AddText(@"osu!", t => t.Font = OsuFont.TorusAlternate);
text.AddText(@"editor", t =>
{
t.Font = OsuFont.TorusAlternate;
t.Colour = colourProvider.Highlight1;
});
} }
protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu(); protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu();

View File

@ -73,6 +73,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
{ {
public MarkerVisualisation() public MarkerVisualisation()
{ {
const float box_height = 4;
Anchor = Anchor.CentreLeft; Anchor = Anchor.CentreLeft;
Origin = Anchor.Centre; Origin = Anchor.Centre;
RelativePositionAxes = Axes.X; RelativePositionAxes = Axes.X;
@ -80,32 +82,46 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
AutoSizeAxes = Axes.X; AutoSizeAxes = Axes.X;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
new Box
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Size = new Vector2(14, box_height),
},
new Triangle new Triangle
{ {
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.BottomCentre, Origin = Anchor.BottomCentre,
Scale = new Vector2(1, -1), Scale = new Vector2(1, -1),
Size = new Vector2(10, 5), Size = new Vector2(10, 5),
Y = box_height,
}, },
new Triangle new Triangle
{ {
Anchor = Anchor.BottomCentre, Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre, Origin = Anchor.BottomCentre,
Size = new Vector2(10, 5) Size = new Vector2(10, 5),
Y = -box_height,
},
new Box
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Size = new Vector2(14, box_height),
}, },
new Box new Box
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
Width = 2, Width = 1.4f,
EdgeSmoothness = new Vector2(1, 0) EdgeSmoothness = new Vector2(1, 0)
} }
}; };
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) => Colour = colours.Red; private void load(OsuColour colours) => Colour = colours.Red1;
} }
} }
} }

View File

@ -33,12 +33,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
{ {
private int? lastCustomDivisor; private int? lastCustomDivisor;
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor(); [Resolved]
private BindableBeatDivisor beatDivisor { get; set; } = null!;
public BeatDivisorControl(BindableBeatDivisor beatDivisor)
{
this.beatDivisor.BindTo(beatDivisor);
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider) private void load(OverlayColourProvider colourProvider)

View File

@ -12,17 +12,17 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{ {
public partial class CentreMarker : CompositeDrawable public partial class CentreMarker : CompositeDrawable
{ {
private const float triangle_width = 15; private const float triangle_width = 8;
private const float triangle_height = 10;
private const float bar_width = 2; private const float bar_width = 1.6f;
public CentreMarker() public CentreMarker()
{ {
RelativeSizeAxes = Axes.Y; RelativeSizeAxes = Axes.Y;
Size = new Vector2(triangle_width, 1); Size = new Vector2(triangle_width, 1);
Anchor = Anchor.Centre; Anchor = Anchor.TopCentre;
Origin = Anchor.Centre; Origin = Anchor.TopCentre;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
@ -37,22 +37,16 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{ {
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.BottomCentre, Origin = Anchor.BottomCentre,
Size = new Vector2(triangle_width, triangle_height), Size = new Vector2(triangle_width, triangle_width * 0.8f),
Scale = new Vector2(1, -1) Scale = new Vector2(1, -1)
}, },
new Triangle
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Size = new Vector2(triangle_width, triangle_height),
}
}; };
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
Colour = colours.RedDark; Colour = colours.Red1;
} }
} }
} }

View File

@ -1,63 +1,68 @@
// 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.
#nullable disable
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.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation; using osu.Game.Localisation;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Resources.Localisation.Web; using osu.Game.Resources.Localisation.Web;
using osu.Game.Rulesets.Edit;
using osuTK; using osuTK;
namespace osu.Game.Screens.Edit.Compose.Components.Timeline namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{ {
public partial class TimelineArea : CompositeDrawable public partial class TimelineArea : CompositeDrawable
{ {
public Timeline Timeline; public Timeline Timeline = null!;
private readonly Drawable userContent; private readonly Drawable userContent;
public TimelineArea(Drawable content = null) public TimelineArea(Drawable? content = null)
{ {
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
userContent = content ?? Drawable.Empty(); userContent = content ?? Empty();
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider) private void load(OverlayColourProvider colourProvider, OsuColour colours)
{ {
Masking = true;
OsuCheckbox waveformCheckbox; OsuCheckbox waveformCheckbox;
OsuCheckbox controlPointsCheckbox; OsuCheckbox controlPointsCheckbox;
OsuCheckbox ticksCheckbox; OsuCheckbox ticksCheckbox;
const float padding = 10;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background5
},
new GridContainer new GridContainer
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
RowDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
},
ColumnDimensions = new[]
{
new Dimension(GridSizeMode.Absolute, 135),
new Dimension(),
new Dimension(GridSizeMode.Absolute, 35),
new Dimension(GridSizeMode.Absolute, HitObjectComposer.TOOLBOX_CONTRACTED_SIZE_RIGHT - padding * 2),
},
Content = new[] Content = new[]
{ {
new Drawable[] new Drawable[]
{ {
new Container new Container
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Both,
AutoSizeAxes = Axes.X,
Name = @"Toggle controls", Name = @"Toggle controls",
Children = new Drawable[] Children = new Drawable[]
{ {
@ -68,24 +73,23 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
}, },
new FillFlowContainer new FillFlowContainer
{ {
AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Both,
Width = 160, Padding = new MarginPadding(padding),
Padding = new MarginPadding(10),
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 4), Spacing = new Vector2(0, 4),
Children = new[] Children = new[]
{ {
waveformCheckbox = new OsuCheckbox waveformCheckbox = new OsuCheckbox(nubSize: 30f)
{ {
LabelText = EditorStrings.TimelineWaveform, LabelText = EditorStrings.TimelineWaveform,
Current = { Value = true }, Current = { Value = true },
}, },
ticksCheckbox = new OsuCheckbox ticksCheckbox = new OsuCheckbox(nubSize: 30f)
{ {
LabelText = EditorStrings.TimelineTicks, LabelText = EditorStrings.TimelineTicks,
Current = { Value = true }, Current = { Value = true },
}, },
controlPointsCheckbox = new OsuCheckbox controlPointsCheckbox = new OsuCheckbox(nubSize: 30f)
{ {
LabelText = BeatmapsetsStrings.ShowStatsBpm, LabelText = BeatmapsetsStrings.ShowStatsBpm,
Current = { Value = true }, Current = { Value = true },
@ -96,29 +100,52 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
}, },
new Container new Container
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.X, AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
// the out-of-bounds portion of the centre marker.
new Box
{
Width = 24,
Height = EditorScreenWithTimeline.PADDING,
Depth = float.MaxValue,
Colour = colours.Red1,
Anchor = Anchor.TopCentre,
Origin = Anchor.BottomCentre,
},
new Box
{
RelativeSizeAxes = Axes.Both,
Depth = float.MaxValue,
Colour = colourProvider.Background5
},
Timeline = new Timeline(userContent),
}
},
new Container
{
RelativeSizeAxes = Axes.Both,
Name = @"Zoom controls", Name = @"Zoom controls",
Padding = new MarginPadding { Right = padding },
Children = new Drawable[] Children = new Drawable[]
{ {
new Box new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background3, Colour = colourProvider.Background2,
}, },
new Container<TimelineButton> new Container<TimelineButton>
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Both,
AutoSizeAxes = Axes.X,
Masking = true,
Children = new[] Children = new[]
{ {
new TimelineButton new TimelineButton
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Both,
Height = 0.5f, Size = new Vector2(1, 0.5f),
Icon = FontAwesome.Solid.SearchPlus, Icon = FontAwesome.Solid.SearchPlus,
Action = () => Timeline.AdjustZoomRelatively(1) Action = () => Timeline.AdjustZoomRelatively(1)
}, },
@ -126,8 +153,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{ {
Anchor = Anchor.BottomLeft, Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft, Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Both,
Height = 0.5f, Size = new Vector2(1, 0.5f),
Icon = FontAwesome.Solid.SearchMinus, Icon = FontAwesome.Solid.SearchMinus,
Action = () => Timeline.AdjustZoomRelatively(-1) Action = () => Timeline.AdjustZoomRelatively(-1)
}, },
@ -135,19 +162,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
} }
} }
}, },
Timeline = new Timeline(userContent), new BeatDivisorControl { RelativeSizeAxes = Axes.Both }
}, },
}, },
RowDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
},
ColumnDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension(GridSizeMode.AutoSize),
new Dimension(),
}
} }
}; };

View File

@ -22,7 +22,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
RelativeSizeAxes = Axes.Y; RelativeSizeAxes = Axes.Y;
AutoSizeAxes = Axes.X; AutoSizeAxes = Axes.X;
Origin = Anchor.TopCentre; Origin = Anchor.TopLeft;
X = (float)group.Time; X = (float)group.Time;
} }

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
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;
@ -10,24 +8,25 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Edit.Compose.Components.Timeline namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{ {
public partial class TopPointPiece : CompositeDrawable public partial class TopPointPiece : CompositeDrawable
{ {
private readonly ControlPoint point; protected readonly ControlPoint Point;
protected OsuSpriteText Label { get; private set; } protected OsuSpriteText Label { get; private set; } = null!;
private const float width = 80;
public TopPointPiece(ControlPoint point) public TopPointPiece(ControlPoint point)
{ {
this.point = point; Point = point;
AutoSizeAxes = Axes.X; Width = width;
Height = 16; Height = 16;
Margin = new MarginPadding(4); Margin = new MarginPadding { Vertical = 4 };
Masking = true;
CornerRadius = Height / 2;
Origin = Anchor.TopCentre; Origin = Anchor.TopCentre;
Anchor = Anchor.TopCentre; Anchor = Anchor.TopCentre;
@ -36,17 +35,52 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
const float corner_radius = 4;
const float arrow_extension = 3;
const float triangle_portion = 15;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{
// This is a triangle, trust me.
// Doing it this way looks okay. Doing it using Triangle primitive is basically impossible.
new Container
{
Colour = Point.GetRepresentingColour(colours),
X = -corner_radius,
Size = new Vector2(triangle_portion * arrow_extension, Height),
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Masking = true,
CornerRadius = Height,
CornerExponent = 1.4f,
Children = new Drawable[]
{ {
new Box new Box
{ {
Colour = point.GetRepresentingColour(colours), Colour = Color4.White,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
}
},
new Container
{
RelativeSizeAxes = Axes.Y,
Width = width - triangle_portion,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Colour = Point.GetRepresentingColour(colours),
Masking = true,
CornerRadius = corner_radius,
Child = new Box
{
Colour = Color4.White,
RelativeSizeAxes = Axes.Both,
},
},
Label = new OsuSpriteText Label = new OsuSpriteText
{ {
Anchor = Anchor.Centre, Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre, Origin = Anchor.CentreLeft,
Padding = new MarginPadding(3), Padding = new MarginPadding(3),
Font = OsuFont.Default.With(size: 14, weight: FontWeight.SemiBold), Font = OsuFont.Default.With(size: 14, weight: FontWeight.SemiBold),
Colour = colours.B5, Colour = colours.B5,

View File

@ -359,7 +359,7 @@ namespace osu.Game.Screens.Edit
{ {
Anchor = Anchor.BottomRight, Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight, Origin = Anchor.BottomRight,
X = -15, X = -10,
Current = Mode, Current = Mode,
}, },
}, },

View File

@ -1,43 +1,37 @@
// 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.
#nullable disable
using JetBrains.Annotations;
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.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Screens.Edit.Compose.Components;
using osu.Game.Screens.Edit.Compose.Components.Timeline; using osu.Game.Screens.Edit.Compose.Components.Timeline;
namespace osu.Game.Screens.Edit namespace osu.Game.Screens.Edit
{ {
public abstract partial class EditorScreenWithTimeline : EditorScreen public abstract partial class EditorScreenWithTimeline : EditorScreen
{ {
private const float padding = 10; public const float PADDING = 10;
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor(); private Container timelineContainer = null!;
private Container timelineContainer; private Container mainContent = null!;
private LoadingSpinner spinner = null!;
protected EditorScreenWithTimeline(EditorScreenMode type) protected EditorScreenWithTimeline(EditorScreenMode type)
: base(type) : base(type)
{ {
} }
private Container mainContent;
private LoadingSpinner spinner;
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(OverlayColourProvider colourProvider, [CanBeNull] BindableBeatDivisor beatDivisor) private void load(OverlayColourProvider colourProvider)
{ {
if (beatDivisor != null) // Grid with only two rows.
this.beatDivisor.BindTo(beatDivisor); // First is the timeline area, which should be allowed to expand as required.
// Second is the main editor content, including the playfield and side toolbars (but not the bottom).
Child = new GridContainer Child = new GridContainer
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
@ -67,7 +61,7 @@ namespace osu.Game.Screens.Edit
Name = "Timeline content", Name = "Timeline content",
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Horizontal = padding, Top = padding }, Padding = new MarginPadding { Horizontal = PADDING, Top = PADDING },
Child = new GridContainer Child = new GridContainer
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
@ -80,9 +74,7 @@ namespace osu.Game.Screens.Edit
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Right = 5 },
}, },
new BeatDivisorControl(this.beatDivisor) { RelativeSizeAxes = Axes.Both }
}, },
}, },
RowDimensions = new[] RowDimensions = new[]

View File

@ -17,8 +17,8 @@ namespace osu.Game.Skinning
Anchor = Anchor.TopRight; Anchor = Anchor.TopRight;
Origin = Anchor.TopRight; Origin = Anchor.TopRight;
Scale = new Vector2(0.6f); Scale = new Vector2(0.6f * 0.96f);
Margin = new MarginPadding(10); Margin = new MarginPadding { Vertical = 9, Horizontal = 17 };
} }
protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(LegacyFont.Score) protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(LegacyFont.Score)

View File

@ -21,7 +21,7 @@ namespace osu.Game.Skinning
Origin = Anchor.TopRight; Origin = Anchor.TopRight;
Scale = new Vector2(0.96f); Scale = new Vector2(0.96f);
Margin = new MarginPadding(10); Margin = new MarginPadding { Horizontal = 10 };
} }
protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(LegacyFont.Score) protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(LegacyFont.Score)

View File

@ -368,7 +368,7 @@ namespace osu.Game.Skinning
{ {
songProgress.Anchor = Anchor.TopRight; songProgress.Anchor = Anchor.TopRight;
songProgress.Origin = Anchor.CentreRight; songProgress.Origin = Anchor.CentreRight;
songProgress.X = -accuracy.ScreenSpaceDeltaToParentSpace(accuracy.ScreenSpaceDrawQuad.Size).X - 10; songProgress.X = -accuracy.ScreenSpaceDeltaToParentSpace(accuracy.ScreenSpaceDrawQuad.Size).X - 18;
songProgress.Y = container.ToLocalSpace(accuracy.ScreenSpaceDrawQuad.TopLeft).Y + (accuracy.ScreenSpaceDeltaToParentSpace(accuracy.ScreenSpaceDrawQuad.Size).Y / 2); songProgress.Y = container.ToLocalSpace(accuracy.ScreenSpaceDrawQuad.TopLeft).Y + (accuracy.ScreenSpaceDeltaToParentSpace(accuracy.ScreenSpaceDrawQuad.Size).Y / 2);
} }
@ -397,8 +397,8 @@ namespace osu.Game.Skinning
new LegacyComboCounter(), new LegacyComboCounter(),
new LegacyScoreCounter(), new LegacyScoreCounter(),
new LegacyAccuracyCounter(), new LegacyAccuracyCounter(),
new LegacyHealthDisplay(),
new LegacySongProgress(), new LegacySongProgress(),
new LegacyHealthDisplay(),
new BarHitErrorMeter(), new BarHitErrorMeter(),
new DefaultKeyCounterDisplay() new DefaultKeyCounterDisplay()
} }