// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.UI; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Components.RadioButtons; namespace osu.Game.Rulesets.Osu.Edit { public partial class OsuGridToolboxGroup : EditorToolboxGroup, IKeyBindingHandler { private static readonly int[] grid_sizes = { 4, 8, 16, 32 }; private int currentGridSizeIndex = grid_sizes.Length - 1; [Resolved] private EditorBeatmap editorBeatmap { get; set; } = null!; public BindableFloat StartPositionX { get; } = new BindableFloat(OsuPlayfield.BASE_SIZE.X / 2) { MinValue = 0f, MaxValue = OsuPlayfield.BASE_SIZE.X, Precision = 1f }; public BindableFloat StartPositionY { get; } = new BindableFloat(OsuPlayfield.BASE_SIZE.Y / 2) { MinValue = 0f, MaxValue = OsuPlayfield.BASE_SIZE.Y, Precision = 1f }; public BindableFloat Spacing { get; } = new BindableFloat(4f) { MinValue = 4f, MaxValue = 128f, Precision = 1f }; public BindableFloat GridLinesRotation { get; } = new BindableFloat(0f) { MinValue = -45f, MaxValue = 45f, Precision = 1f }; public Bindable GridType { get; } = new Bindable(); private ExpandableSlider startPositionXSlider = null!; private ExpandableSlider startPositionYSlider = null!; private ExpandableSlider spacingSlider = null!; private ExpandableSlider gridLinesRotationSlider = null!; private EditorRadioButtonCollection gridTypeButtons = null!; public OsuGridToolboxGroup() : base("grid") { } [BackgroundDependencyLoader] private void load() { Children = new Drawable[] { startPositionXSlider = new ExpandableSlider { Current = StartPositionX }, startPositionYSlider = new ExpandableSlider { Current = StartPositionY }, spacingSlider = new ExpandableSlider { Current = Spacing }, gridLinesRotationSlider = new ExpandableSlider { Current = GridLinesRotation }, gridTypeButtons = new EditorRadioButtonCollection { RelativeSizeAxes = Axes.X, Items = new[] { new RadioButton("Square", () => GridType.Value = PositionSnapGridType.Square, () => new SpriteIcon { Icon = FontAwesome.Regular.Square }), new RadioButton("Triangle", () => GridType.Value = PositionSnapGridType.Triangle, () => new Triangle()), new RadioButton("Circle", () => GridType.Value = PositionSnapGridType.Circle, () => new SpriteIcon { Icon = FontAwesome.Regular.Circle }), } }, }; int gridSizeIndex = Array.IndexOf(grid_sizes, editorBeatmap.BeatmapInfo.GridSize); if (gridSizeIndex >= 0) currentGridSizeIndex = gridSizeIndex; updateSpacing(); } protected override void LoadComplete() { base.LoadComplete(); gridTypeButtons.Items.First().Select(); StartPositionX.BindValueChanged(x => { startPositionXSlider.ContractedLabelText = $"X: {x.NewValue:N0}"; startPositionXSlider.ExpandedLabelText = $"X Offset: {x.NewValue:N0}"; }, true); StartPositionY.BindValueChanged(y => { startPositionYSlider.ContractedLabelText = $"Y: {y.NewValue:N0}"; startPositionYSlider.ExpandedLabelText = $"Y Offset: {y.NewValue:N0}"; }, true); Spacing.BindValueChanged(spacing => { spacingSlider.ContractedLabelText = $"S: {spacing.NewValue:N0}"; spacingSlider.ExpandedLabelText = $"Spacing: {spacing.NewValue:N0}"; }, true); GridLinesRotation.BindValueChanged(rotation => { gridLinesRotationSlider.ContractedLabelText = $"R: {rotation.NewValue:N0}"; gridLinesRotationSlider.ExpandedLabelText = $"Rotation: {rotation.NewValue:N0}"; }, true); } private void nextGridSize() { currentGridSizeIndex = (currentGridSizeIndex + 1) % grid_sizes.Length; updateSpacing(); } private void updateSpacing() { int gridSize = grid_sizes[currentGridSizeIndex]; editorBeatmap.BeatmapInfo.GridSize = gridSize; Spacing.Value = gridSize; } public bool OnPressed(KeyBindingPressEvent e) { switch (e.Action) { case GlobalAction.EditorCycleGridDisplayMode: nextGridSize(); return true; } return false; } public void OnReleased(KeyBindingReleaseEvent e) { } } public enum PositionSnapGridType { Square, Triangle, Circle, } }