mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 18:23:04 +08:00
Remove old mod buttons
This commit is contained in:
parent
8b0ece1c09
commit
33634cba1e
@ -1,64 +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 osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Game.Overlays.Mods;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.UserInterface
|
|
||||||
{
|
|
||||||
public class TestSceneModButton : OsuTestScene
|
|
||||||
{
|
|
||||||
public TestSceneModButton()
|
|
||||||
{
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new ModButton(new MultiMod(new TestMod1(), new TestMod2(), new TestMod3(), new TestMod4()))
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestMod1 : TestMod
|
|
||||||
{
|
|
||||||
public override string Name => "Test mod 1";
|
|
||||||
|
|
||||||
public override string Acronym => "M1";
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestMod2 : TestMod
|
|
||||||
{
|
|
||||||
public override string Name => "Test mod 2";
|
|
||||||
|
|
||||||
public override string Acronym => "M2";
|
|
||||||
|
|
||||||
public override IconUsage? Icon => FontAwesome.Solid.Exclamation;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestMod3 : TestMod
|
|
||||||
{
|
|
||||||
public override string Name => "Test mod 3";
|
|
||||||
|
|
||||||
public override string Acronym => "M3";
|
|
||||||
|
|
||||||
public override IconUsage? Icon => FontAwesome.Solid.ArrowRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestMod4 : TestMod
|
|
||||||
{
|
|
||||||
public override string Name => "Test mod 4";
|
|
||||||
|
|
||||||
public override string Acronym => "M4";
|
|
||||||
}
|
|
||||||
|
|
||||||
private abstract class TestMod : Mod, IApplicableMod
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.0;
|
|
||||||
|
|
||||||
public override string Description => "This is a test mod.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +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 osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Cursor;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osuTK;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Mods
|
|
||||||
{
|
|
||||||
public class IncompatibleIcon : VisibilityContainer, IHasTooltip
|
|
||||||
{
|
|
||||||
private Circle circle;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuColour colours)
|
|
||||||
{
|
|
||||||
Size = new Vector2(20);
|
|
||||||
|
|
||||||
State.Value = Visibility.Hidden;
|
|
||||||
Alpha = 0;
|
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
|
||||||
{
|
|
||||||
circle = new Circle
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Colour = colours.Gray4,
|
|
||||||
},
|
|
||||||
new SpriteIcon
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Size = new Vector2(0.6f),
|
|
||||||
Icon = FontAwesome.Solid.Slash,
|
|
||||||
Colour = Color4.White,
|
|
||||||
Shadow = true,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void PopIn()
|
|
||||||
{
|
|
||||||
this.FadeIn(200, Easing.OutQuint);
|
|
||||||
circle.FlashColour(Color4.Red, 500, Easing.OutQuint);
|
|
||||||
this.ScaleTo(1.8f).Then().ScaleTo(1, 500, Easing.OutQuint);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void PopOut()
|
|
||||||
{
|
|
||||||
this.FadeOut(200, Easing.OutQuint);
|
|
||||||
this.ScaleTo(0.8f, 200, Easing.In);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalisableString TooltipText => "Incompatible with current selected mods";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,319 +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 osuTK;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
using osuTK.Input;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Graphics.Cursor;
|
|
||||||
using osu.Framework.Input.Events;
|
|
||||||
using osu.Framework.Localisation;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Mods
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a clickable button which can cycle through one of more mods.
|
|
||||||
/// </summary>
|
|
||||||
public class ModButton : ModButtonEmpty, IHasCustomTooltip<Mod>
|
|
||||||
{
|
|
||||||
private ModIcon foregroundIcon;
|
|
||||||
private ModIcon backgroundIcon;
|
|
||||||
private readonly SpriteText text;
|
|
||||||
private readonly Container<ModIcon> iconsContainer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fired when the selection changes.
|
|
||||||
/// </summary>
|
|
||||||
public Action<Mod> SelectionChanged;
|
|
||||||
|
|
||||||
public LocalisableString TooltipText => (SelectedMod?.Description ?? Mods.FirstOrDefault()?.Description) ?? string.Empty;
|
|
||||||
|
|
||||||
private const Easing mod_switch_easing = Easing.InOutSine;
|
|
||||||
private const double mod_switch_duration = 120;
|
|
||||||
|
|
||||||
// A selected index of -1 means not selected.
|
|
||||||
private int selectedIndex = -1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Change the selected mod index of this button.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="newIndex">The new index.</param>
|
|
||||||
/// <param name="resetSettings">Whether any settings applied to the mod should be reset on selection.</param>
|
|
||||||
/// <returns>Whether the selection changed.</returns>
|
|
||||||
private bool changeSelectedIndex(int newIndex, bool resetSettings = true)
|
|
||||||
{
|
|
||||||
if (newIndex == selectedIndex) return false;
|
|
||||||
|
|
||||||
int direction = newIndex < selectedIndex ? -1 : 1;
|
|
||||||
|
|
||||||
bool beforeSelected = Selected;
|
|
||||||
|
|
||||||
Mod previousSelection = SelectedMod ?? Mods[0];
|
|
||||||
|
|
||||||
if (newIndex >= Mods.Length)
|
|
||||||
newIndex = -1;
|
|
||||||
else if (newIndex < -1)
|
|
||||||
newIndex = Mods.Length - 1;
|
|
||||||
|
|
||||||
if (newIndex >= 0 && !Mods[newIndex].HasImplementation)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
selectedIndex = newIndex;
|
|
||||||
|
|
||||||
Mod newSelection = SelectedMod ?? Mods[0];
|
|
||||||
|
|
||||||
if (resetSettings)
|
|
||||||
newSelection.ResetSettingsToDefaults();
|
|
||||||
|
|
||||||
Schedule(() =>
|
|
||||||
{
|
|
||||||
if (beforeSelected != Selected)
|
|
||||||
{
|
|
||||||
iconsContainer.RotateTo(Selected ? 5f : 0f, 300, Easing.OutElastic);
|
|
||||||
iconsContainer.ScaleTo(Selected ? 1.1f : 1f, 300, Easing.OutElastic);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (previousSelection != newSelection)
|
|
||||||
{
|
|
||||||
const float rotate_angle = 16;
|
|
||||||
|
|
||||||
foregroundIcon.RotateTo(rotate_angle * direction, mod_switch_duration, mod_switch_easing);
|
|
||||||
backgroundIcon.RotateTo(-rotate_angle * direction, mod_switch_duration, mod_switch_easing);
|
|
||||||
|
|
||||||
backgroundIcon.Mod = newSelection;
|
|
||||||
|
|
||||||
using (BeginDelayedSequence(mod_switch_duration))
|
|
||||||
{
|
|
||||||
foregroundIcon
|
|
||||||
.RotateTo(-rotate_angle * direction)
|
|
||||||
.RotateTo(0f, mod_switch_duration, mod_switch_easing);
|
|
||||||
|
|
||||||
backgroundIcon
|
|
||||||
.RotateTo(rotate_angle * direction)
|
|
||||||
.RotateTo(0f, mod_switch_duration, mod_switch_easing);
|
|
||||||
|
|
||||||
Schedule(() => DisplayMod(newSelection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foregroundIcon.Selected.Value = Selected;
|
|
||||||
});
|
|
||||||
|
|
||||||
SelectionChanged?.Invoke(SelectedMod);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Selected => selectedIndex != -1;
|
|
||||||
|
|
||||||
private Color4 selectedColour;
|
|
||||||
|
|
||||||
public Color4 SelectedColour
|
|
||||||
{
|
|
||||||
get => selectedColour;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == selectedColour) return;
|
|
||||||
|
|
||||||
selectedColour = value;
|
|
||||||
if (Selected) foregroundIcon.Colour = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Mod mod;
|
|
||||||
|
|
||||||
protected readonly Container ButtonContent;
|
|
||||||
|
|
||||||
public Mod Mod
|
|
||||||
{
|
|
||||||
get => mod;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
mod = value;
|
|
||||||
|
|
||||||
if (mod == null)
|
|
||||||
{
|
|
||||||
Mods = Array.Empty<Mod>();
|
|
||||||
Alpha = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Mods = (mod as MultiMod)?.Mods ?? new[] { mod };
|
|
||||||
Alpha = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
createIcons();
|
|
||||||
|
|
||||||
if (Mods.Length > 0)
|
|
||||||
{
|
|
||||||
DisplayMod(Mods[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mod[] Mods { get; private set; }
|
|
||||||
|
|
||||||
public virtual Mod SelectedMod => Mods.ElementAtOrDefault(selectedIndex);
|
|
||||||
|
|
||||||
protected override bool OnMouseDown(MouseDownEvent e)
|
|
||||||
{
|
|
||||||
ButtonContent.ScaleTo(0.9f, 800, Easing.Out);
|
|
||||||
return base.OnMouseDown(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMouseUp(MouseUpEvent e)
|
|
||||||
{
|
|
||||||
ButtonContent.ScaleTo(1, 500, Easing.OutElastic);
|
|
||||||
|
|
||||||
// only trigger the event if we are inside the area of the button
|
|
||||||
if (Contains(e.ScreenSpaceMousePosition))
|
|
||||||
{
|
|
||||||
switch (e.Button)
|
|
||||||
{
|
|
||||||
case MouseButton.Right:
|
|
||||||
SelectNext(-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnClick(ClickEvent e)
|
|
||||||
{
|
|
||||||
SelectNext(1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Select the next available mod in a specified direction.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="direction">1 for forwards, -1 for backwards.</param>
|
|
||||||
public void SelectNext(int direction)
|
|
||||||
{
|
|
||||||
int start = selectedIndex + direction;
|
|
||||||
// wrap around if we are at an extremity.
|
|
||||||
if (start >= Mods.Length)
|
|
||||||
start = -1;
|
|
||||||
else if (start < -1)
|
|
||||||
start = Mods.Length - 1;
|
|
||||||
|
|
||||||
for (int i = start; i < Mods.Length && i >= 0; i += direction)
|
|
||||||
{
|
|
||||||
if (SelectAt(i))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Deselect();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Select the mod at the provided index.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="index">The index to select.</param>
|
|
||||||
/// <param name="resetSettings">Whether any settings applied to the mod should be reset on selection.</param>
|
|
||||||
/// <returns>Whether the selection changed.</returns>
|
|
||||||
public bool SelectAt(int index, bool resetSettings = true)
|
|
||||||
{
|
|
||||||
if (!Mods[index].HasImplementation) return false;
|
|
||||||
|
|
||||||
changeSelectedIndex(index, resetSettings);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Deselect() => changeSelectedIndex(-1);
|
|
||||||
|
|
||||||
protected virtual void DisplayMod(Mod mod)
|
|
||||||
{
|
|
||||||
if (backgroundIcon != null)
|
|
||||||
backgroundIcon.Mod = foregroundIcon.Mod;
|
|
||||||
foregroundIcon.Mod = mod;
|
|
||||||
text.Text = mod.Name;
|
|
||||||
Colour = mod.HasImplementation ? Color4.White : Color4.Gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createIcons()
|
|
||||||
{
|
|
||||||
iconsContainer.Clear();
|
|
||||||
|
|
||||||
if (Mods.Length > 1)
|
|
||||||
{
|
|
||||||
iconsContainer.AddRange(new[]
|
|
||||||
{
|
|
||||||
backgroundIcon = new ModIcon(Mods[1], false)
|
|
||||||
{
|
|
||||||
Origin = Anchor.BottomRight,
|
|
||||||
Anchor = Anchor.BottomRight,
|
|
||||||
Position = new Vector2(1.5f),
|
|
||||||
},
|
|
||||||
foregroundIcon = new ModIcon(Mods[0], false)
|
|
||||||
{
|
|
||||||
Origin = Anchor.BottomRight,
|
|
||||||
Anchor = Anchor.BottomRight,
|
|
||||||
Position = new Vector2(-1.5f),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iconsContainer.Add(foregroundIcon = new ModIcon(Mod, false)
|
|
||||||
{
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModButton(Mod mod)
|
|
||||||
{
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
Size = new Vector2(77f, 80f),
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
ButtonContent = new Container
|
|
||||||
{
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
iconsContainer = new Container<ModIcon>
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
text = new OsuSpriteText
|
|
||||||
{
|
|
||||||
Y = 75,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Font = OsuFont.GetFont(size: 18)
|
|
||||||
},
|
|
||||||
new HoverSounds()
|
|
||||||
};
|
|
||||||
Mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual ITooltip<Mod> GetCustomTooltip() => new ModButtonTooltip();
|
|
||||||
|
|
||||||
public Mod TooltipContent => SelectedMod ?? Mods.FirstOrDefault();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +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 osuTK;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Mods
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A mod button used exclusively for providing an empty space the size of a mod button.
|
|
||||||
/// </summary>
|
|
||||||
public class ModButtonEmpty : Container
|
|
||||||
{
|
|
||||||
public ModButtonEmpty()
|
|
||||||
{
|
|
||||||
Size = new Vector2(100f);
|
|
||||||
AlwaysPresent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user