Merge branch 'master' into TextLengthLimit

This commit is contained in:
Dan Balasescu
2019-05-15 19:21:01 +09:00
committed by GitHub
1681 changed files with 60763 additions and 27938 deletions

View File

@ -1,12 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using OpenTK.Graphics;
using osu.Game.Graphics.Textures;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Graphics.Backgrounds
{
@ -28,7 +27,6 @@ namespace osu.Game.Graphics.Backgrounds
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = Color4.DarkGray,
FillMode = FillMode.Fill,
});
}

View File

@ -1,14 +1,14 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics;
using osu.Framework.MathUtils;
using OpenTK;
using OpenTK.Graphics;
using osuTK;
using osuTK.Graphics;
using System;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Textures;
using OpenTK.Graphics.ES30;
using osuTK.Graphics.ES30;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Allocation;
@ -30,10 +30,6 @@ namespace osu.Game.Graphics.Backgrounds
/// </summary>
private const float edge_smoothness = 1;
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
public Color4 ColourLight = Color4.White;
public Color4 ColourDark = Color4.Black;
@ -68,7 +64,7 @@ namespace osu.Game.Graphics.Backgrounds
private readonly SortedList<TriangleParticle> parts = new SortedList<TriangleParticle>(Comparer<TriangleParticle>.Default);
private Shader shader;
private IShader shader;
private readonly Texture texture;
public Triangles()
@ -79,7 +75,7 @@ namespace osu.Game.Graphics.Backgrounds
[BackgroundDependencyLoader]
private void load(ShaderManager shaders)
{
shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED);
shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED);
}
protected override void LoadComplete()
@ -90,7 +86,7 @@ namespace osu.Game.Graphics.Backgrounds
public float TriangleScale
{
get { return triangleScale; }
get => triangleScale;
set
{
float change = value / triangleScale;
@ -114,10 +110,10 @@ namespace osu.Game.Graphics.Backgrounds
if (CreateNewTriangles)
addTriangles(false);
float adjustedAlpha = HideAlphaDiscrepancies ?
float adjustedAlpha = HideAlphaDiscrepancies
// Cubically scale alpha to make it drop off more sharply.
(float)Math.Pow(DrawInfo.Colour.AverageColour.Linear.A, 3) :
1;
? (float)Math.Pow(DrawColourInfo.Colour.AverageColour.Linear.A, 3)
: 1;
float elapsedSeconds = (float)Time.Elapsed / 1000;
// Since position is relative, the velocity needs to scale inversely with DrawHeight.
@ -182,71 +178,75 @@ namespace osu.Game.Graphics.Backgrounds
/// <returns>The colour.</returns>
protected virtual Color4 CreateTriangleShade() => Interpolation.ValueAt(RNG.NextSingle(), ColourDark, ColourLight, 0, 1);
protected override DrawNode CreateDrawNode() => new TrianglesDrawNode();
private readonly TrianglesDrawNodeSharedData sharedData = new TrianglesDrawNodeSharedData();
protected override void ApplyDrawNode(DrawNode node)
{
base.ApplyDrawNode(node);
var trianglesNode = (TrianglesDrawNode)node;
trianglesNode.Shader = shader;
trianglesNode.Texture = texture;
trianglesNode.Size = DrawSize;
trianglesNode.Shared = sharedData;
trianglesNode.Parts.Clear();
trianglesNode.Parts.AddRange(parts);
}
private class TrianglesDrawNodeSharedData
{
public readonly LinearBatch<TexturedVertex2D> VertexBatch = new LinearBatch<TexturedVertex2D>(100 * 3, 10, PrimitiveType.Triangles);
}
protected override DrawNode CreateDrawNode() => new TrianglesDrawNode(this);
private class TrianglesDrawNode : DrawNode
{
public Shader Shader;
public Texture Texture;
protected new Triangles Source => (Triangles)base.Source;
public TrianglesDrawNodeSharedData Shared;
private IShader shader;
private Texture texture;
public readonly List<TriangleParticle> Parts = new List<TriangleParticle>();
public Vector2 Size;
private readonly List<TriangleParticle> parts = new List<TriangleParticle>();
private Vector2 size;
private readonly LinearBatch<TexturedVertex2D> vertexBatch = new LinearBatch<TexturedVertex2D>(100 * 3, 10, PrimitiveType.Triangles);
public TrianglesDrawNode(Triangles source)
: base(source)
{
}
public override void ApplyState()
{
base.ApplyState();
shader = Source.shader;
texture = Source.texture;
size = Source.DrawSize;
parts.Clear();
parts.AddRange(Source.parts);
}
public override void Draw(Action<TexturedVertex2D> vertexAction)
{
base.Draw(vertexAction);
Shader.Bind();
Texture.TextureGL.Bind();
shader.Bind();
texture.TextureGL.Bind();
Vector2 localInflationAmount = edge_smoothness * DrawInfo.MatrixInverse.ExtractScale().Xy;
foreach (TriangleParticle particle in Parts)
foreach (TriangleParticle particle in parts)
{
var offset = triangle_size * new Vector2(particle.Scale * 0.5f, particle.Scale * 0.866f);
var size = new Vector2(2 * offset.X, offset.Y);
var triangle = new Triangle(
Vector2Extensions.Transform(particle.Position * Size, DrawInfo.Matrix),
Vector2Extensions.Transform(particle.Position * Size + offset, DrawInfo.Matrix),
Vector2Extensions.Transform(particle.Position * Size + new Vector2(-offset.X, offset.Y), DrawInfo.Matrix)
Vector2Extensions.Transform(particle.Position * size, DrawInfo.Matrix),
Vector2Extensions.Transform(particle.Position * size + offset, DrawInfo.Matrix),
Vector2Extensions.Transform(particle.Position * size + new Vector2(-offset.X, offset.Y), DrawInfo.Matrix)
);
ColourInfo colourInfo = DrawInfo.Colour;
ColourInfo colourInfo = DrawColourInfo.Colour;
colourInfo.ApplyChild(particle.Colour);
Texture.DrawTriangle(
texture.DrawTriangle(
triangle,
colourInfo,
null,
Shared.VertexBatch.AddAction,
Vector2.Divide(localInflationAmount, size));
vertexBatch.AddAction,
Vector2.Divide(localInflationAmount, new Vector2(2 * offset.X, offset.Y)));
}
Shader.Unbind();
shader.Unbind();
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
vertexBatch.Dispose();
}
}

View File

@ -1,9 +1,9 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
@ -74,7 +74,7 @@ namespace osu.Game.Graphics.Containers
}
[BackgroundDependencyLoader]
private void load(IBindableBeatmap beatmap)
private void load(IBindable<WorkingBeatmap> beatmap)
{
Beatmap.BindTo(beatmap);
}

View File

@ -1,10 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using OpenTK;
using osu.Framework.Graphics.Effects;
using osuTK;
namespace osu.Game.Graphics.Containers
{
@ -15,15 +16,9 @@ namespace osu.Game.Graphics.Containers
{
public Drawable Icon
{
get
{
return InternalChild;
}
get => InternalChild;
set
{
InternalChild = value;
}
set => InternalChild = value;
}
/// <summary>
@ -33,13 +28,14 @@ namespace osu.Game.Graphics.Containers
/// </summary>
public new EdgeEffectParameters EdgeEffect
{
get { return base.EdgeEffect; }
set { base.EdgeEffect = value; }
get => base.EdgeEffect;
set => base.EdgeEffect = value;
}
protected override void Update()
{
base.Update();
if (InternalChildren.Count > 0 && InternalChild.DrawSize.X > 0)
{
// We're modifying scale here for a few reasons

View File

@ -1,8 +1,8 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;

View File

@ -1,15 +1,17 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Game.Online.Chat;
using System;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Users;
namespace osu.Game.Graphics.Containers
{
@ -20,22 +22,21 @@ namespace osu.Game.Graphics.Containers
{
}
public override bool HandleMouseInput => true;
private OsuGame game;
private ChannelManager channelManager;
private Action showNotImplementedError;
[BackgroundDependencyLoader(true)]
private void load(OsuGame game, NotificationOverlay notifications)
private void load(OsuGame game, NotificationOverlay notifications, ChannelManager channelManager)
{
// will be null in tests
this.game = game;
this.channelManager = channelManager;
showNotImplementedError = () => notifications?.Post(new SimpleNotification
{
Text = @"This link type is not yet supported!",
Icon = FontAwesome.fa_life_saver,
Icon = FontAwesome.Solid.LifeRing,
});
}
@ -51,6 +52,7 @@ namespace osu.Game.Graphics.Containers
}
int previousLinkEnd = 0;
foreach (var link in links)
{
AddText(text.Substring(previousLinkEnd, link.Index - previousLinkEnd));
@ -61,12 +63,30 @@ namespace osu.Game.Graphics.Containers
AddText(text.Substring(previousLinkEnd));
}
public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action<SpriteText> creationParameters = null)
public IEnumerable<Drawable> AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action<SpriteText> creationParameters = null)
=> createLink(AddText(text, creationParameters), text, url, linkType, linkArgument, tooltipText);
public IEnumerable<Drawable> AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
=> createLink(AddText(text, creationParameters), text, tooltipText: tooltipText, action: action);
public IEnumerable<Drawable> AddLink(IEnumerable<SpriteText> text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null)
{
AddInternal(new DrawableLinkCompiler(AddText(text, creationParameters).ToList())
foreach (var t in text)
AddArbitraryDrawable(t);
return createLink(text, null, url, linkType, linkArgument, tooltipText);
}
public IEnumerable<Drawable> AddUserLink(User user, Action<SpriteText> creationParameters = null)
=> createLink(AddText(user.Username, creationParameters), user.Username, null, LinkAction.OpenUserProfile, user.Id.ToString(), "View profile");
private IEnumerable<Drawable> createLink(IEnumerable<Drawable> drawables, string text, string url = null, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action action = null)
{
AddInternal(new DrawableLinkCompiler(drawables.OfType<SpriteText>().ToList())
{
RelativeSizeAxes = Axes.Both,
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
Action = () =>
Action = action ?? (() =>
{
switch (linkType)
{
@ -75,30 +95,51 @@ namespace osu.Game.Graphics.Containers
if (linkArgument != null && int.TryParse(linkArgument.Contains('?') ? linkArgument.Split('?')[0] : linkArgument, out int beatmapId))
game?.ShowBeatmap(beatmapId);
break;
case LinkAction.OpenBeatmapSet:
if (int.TryParse(linkArgument, out int setId))
game?.ShowBeatmapSet(setId);
break;
case LinkAction.OpenChannel:
game?.OpenChannel(linkArgument);
try
{
channelManager?.OpenChannel(linkArgument);
}
catch (ChannelNotFoundException)
{
Logger.Log($"The requested channel \"{linkArgument}\" does not exist");
}
break;
case LinkAction.OpenEditorTimestamp:
case LinkAction.JoinMultiplayerMatch:
case LinkAction.Spectate:
showNotImplementedError?.Invoke();
break;
case LinkAction.External:
Process.Start(url);
game?.OpenUrlExternally(url);
break;
case LinkAction.OpenUserProfile:
if (long.TryParse(linkArgument, out long userId))
game?.ShowUser(userId);
break;
default:
throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action.");
}
},
}),
});
return drawables;
}
// We want the compilers to always be visible no matter where they are, so RelativeSizeAxes is used.
// However due to https://github.com/ppy/osu-framework/issues/2073, it's possible for the compilers to be relative size in the flow's auto-size axes - an unsupported operation.
// Since the compilers don't display any content and don't affect the layout, it's simplest to exclude them from the flow.
public override IEnumerable<Drawable> FlowingChildren => base.FlowingChildren.Where(c => !(c is DrawableLinkCompiler));
}
}

View File

@ -0,0 +1,157 @@
// 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.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Game.Screens.Menu;
using osuTK;
namespace osu.Game.Graphics.Containers
{
/// <summary>
/// A container that handles tracking of an <see cref="OsuLogo"/> through different layout scenarios.
/// </summary>
public class LogoTrackingContainer : Container
{
public Facade LogoFacade => facade;
protected OsuLogo Logo { get; private set; }
private readonly InternalFacade facade = new InternalFacade();
private Easing easing;
private Vector2? startPosition;
private double? startTime;
private double duration;
/// <summary>
/// Assign the logo that should track the facade's position, as well as how it should transform to its initial position.
/// </summary>
/// <param name="logo">The instance of the logo to be used for tracking.</param>
/// <param name="duration">The duration of the initial transform. Default is instant.</param>
/// <param name="easing">The easing type of the initial transform.</param>
public void StartTracking(OsuLogo logo, double duration = 0, Easing easing = Easing.None)
{
if (logo == null)
throw new ArgumentNullException(nameof(logo));
if (logo.IsTracking && Logo == null)
throw new InvalidOperationException($"Cannot track an instance of {typeof(OsuLogo)} to multiple {typeof(LogoTrackingContainer)}s");
if (Logo != logo && Logo != null)
{
// If we're replacing the logo to be tracked, the old one no longer has a tracking container
Logo.IsTracking = false;
}
Logo = logo;
Logo.IsTracking = true;
this.duration = duration;
this.easing = easing;
startTime = null;
startPosition = null;
}
/// <summary>
/// Stops the logo assigned in <see cref="StartTracking"/> from tracking the facade's position.
/// </summary>
public void StopTracking()
{
if (Logo != null)
{
Logo.IsTracking = false;
Logo = null;
}
}
/// <summary>
/// Gets the position that the logo should move to with respect to the <see cref="LogoFacade"/>.
/// Manually performs a conversion of the Facade's position to the Logo's parent's relative space.
/// </summary>
/// <remarks>Will only be correct if the logo's <see cref="Drawable.RelativePositionAxes"/> are set to Axes.Both</remarks>
protected Vector2 ComputeLogoTrackingPosition()
{
var absolutePos = Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre);
return new Vector2(absolutePos.X / Logo.Parent.RelativeToAbsoluteFactor.X,
absolutePos.Y / Logo.Parent.RelativeToAbsoluteFactor.Y);
}
protected override void Update()
{
base.Update();
if (Logo == null)
return;
if (Logo.RelativePositionAxes != Axes.Both)
throw new InvalidOperationException($"Tracking logo must have {nameof(RelativePositionAxes)} = Axes.Both");
// Account for the scale of the actual OsuLogo, as SizeForFlow only accounts for the sprite scale.
facade.SetSize(new Vector2(Logo.SizeForFlow * Logo.Scale.X));
var localPos = ComputeLogoTrackingPosition();
if (LogoFacade.Parent != null && Logo.Position != localPos)
{
// If this is our first update since tracking has started, initialize our starting values for interpolation
if (startTime == null || startPosition == null)
{
startTime = Time.Current;
startPosition = Logo.Position;
}
if (duration != 0)
{
double elapsedDuration = (double)(Time.Current - startTime);
var amount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1));
// Interpolate the position of the logo, where amount 0 is where the logo was when it first began interpolating, and amount 1 is the target location.
Logo.Position = Vector2.Lerp(startPosition.Value, localPos, amount);
}
else
{
Logo.Position = localPos;
}
}
}
protected override void Dispose(bool isDisposing)
{
if (Logo != null)
Logo.IsTracking = false;
base.Dispose(isDisposing);
}
private class InternalFacade : Facade
{
public new void SetSize(Vector2 size)
{
base.SetSize(size);
}
}
/// <summary>
/// A dummy object used to denote another object's location.
/// </summary>
public abstract class Facade : Drawable
{
public override Vector2 Size
{
get => base.Size;
set => throw new InvalidOperationException($"Cannot set the Size of a {typeof(Facade)} outside of a {typeof(LogoTrackingContainer)}");
}
protected void SetSize(Vector2 size)
{
base.Size = size;
}
}
}
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Graphics;

View File

@ -1,26 +1,52 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using OpenTK;
using osu.Framework.Configuration;
using osuTK;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Audio;
using osu.Game.Input.Bindings;
using osu.Game.Overlays;
namespace osu.Game.Graphics.Containers
{
public class OsuFocusedOverlayContainer : FocusedOverlayContainer
public class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler<GlobalAction>
{
private SampleChannel samplePopIn;
private SampleChannel samplePopOut;
protected virtual bool PlaySamplesOnStateChange => true;
protected override bool BlockNonPositionalInput => true;
/// <summary>
/// Temporary to allow for overlays in the main screen content to not dim theirselves.
/// Should be eventually replaced by dimming which is aware of the target dim container (traverse parent for certain interface type?).
/// </summary>
protected virtual bool DimMainContent => true;
[Resolved(CanBeNull = true)]
private OsuGame osuGame { get; set; }
[Resolved]
private PreviewTrackManager previewTrackManager { get; set; }
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.CacheAs<IPreviewTrackOwner>(this);
return dependencies;
}
[BackgroundDependencyLoader(true)]
private void load(OsuGame osuGame, AudioManager audio)
private void load(AudioManager audio)
{
if (osuGame != null)
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
@ -35,36 +61,71 @@ namespace osu.Game.Graphics.Containers
/// Whether mouse input should be blocked screen-wide while this overlay is visible.
/// Performing mouse actions outside of the valid extents will hide the overlay.
/// </summary>
public virtual bool BlockScreenWideMouse => BlockPassThroughMouse;
public virtual bool BlockScreenWideMouse => BlockPositionalInput;
// receive input outside our bounds so we can trigger a close event on ourselves.
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => BlockScreenWideMouse || base.ReceiveMouseInputAt(screenSpacePos);
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => BlockScreenWideMouse || base.ReceivePositionalInputAt(screenSpacePos);
protected override bool OnClick(InputState state)
protected override bool OnClick(ClickEvent e)
{
if (!base.ReceiveMouseInputAt(state.Mouse.NativeState.Position))
if (!base.ReceivePositionalInputAt(e.ScreenSpaceMousePosition))
{
State = Visibility.Hidden;
return true;
}
return base.OnClick(state);
return base.OnClick(e);
}
public virtual bool OnPressed(GlobalAction action)
{
switch (action)
{
case GlobalAction.Back:
State = Visibility.Hidden;
return true;
case GlobalAction.Select:
return true;
}
return false;
}
public bool OnReleased(GlobalAction action) => false;
private void onStateChanged(Visibility visibility)
{
switch (visibility)
{
case Visibility.Visible:
if (OverlayActivationMode != OverlayActivation.Disabled)
samplePopIn?.Play();
if (OverlayActivationMode.Value != OverlayActivation.Disabled)
{
if (PlaySamplesOnStateChange) samplePopIn?.Play();
if (BlockScreenWideMouse && DimMainContent) osuGame?.AddBlockingOverlay(this);
}
else
State = Visibility.Hidden;
break;
case Visibility.Hidden:
samplePopOut?.Play();
if (PlaySamplesOnStateChange) samplePopOut?.Play();
if (BlockScreenWideMouse) osuGame?.RemoveBlockingOverlay(this);
break;
}
}
protected override void PopOut()
{
base.PopOut();
previewTrackManager.StopAnyPlaying(this);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
osuGame?.RemoveBlockingOverlay(this);
}
}
}

View File

@ -1,39 +1,42 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System.Collections.Generic;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osuTK.Graphics;
using System.Collections.Generic;
namespace osu.Game.Graphics.Containers
{
public class OsuHoverContainer : OsuClickableContainer
{
protected const float FADE_DURATION = 500;
protected Color4 HoverColour;
protected Color4 IdleColour = Color4.White;
protected virtual IEnumerable<Drawable> EffectTargets => new[] { Content };
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
EffectTargets.ForEach(d => d.FadeColour(HoverColour, 500, Easing.OutQuint));
return base.OnHover(state);
EffectTargets.ForEach(d => d.FadeColour(HoverColour, FADE_DURATION, Easing.OutQuint));
return base.OnHover(e);
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
EffectTargets.ForEach(d => d.FadeColour(IdleColour, 500, Easing.OutQuint));
base.OnHoverLost(state);
EffectTargets.ForEach(d => d.FadeColour(IdleColour, FADE_DURATION, Easing.OutQuint));
base.OnHoverLost(e);
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
HoverColour = colours.Yellow;
if (HoverColour == default)
HoverColour = colours.Yellow;
}
protected override void LoadComplete()

View File

@ -1,9 +1,9 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using OpenTK.Input;
using osu.Framework.Input.Events;
using osuTK.Input;
namespace osu.Game.Graphics.Containers
{
@ -20,7 +20,7 @@ namespace osu.Game.Graphics.Containers
/// </summary>
public double DistanceDecayOnRightMouseScrollbar = 0.02;
private bool shouldPerformRightMouseScroll(InputState state) => RightMouseScrollbar && state.Mouse.IsPressed(MouseButton.Right);
private bool shouldPerformRightMouseScroll(MouseButtonEvent e) => RightMouseScrollbar && e.Button == MouseButton.Right;
private void scrollToRelative(float value) => ScrollTo(Clamp((value - Scrollbar.DrawSize[ScrollDim] / 2) / Scrollbar.Size[ScrollDim]), true, DistanceDecayOnRightMouseScrollbar);
@ -28,40 +28,40 @@ namespace osu.Game.Graphics.Containers
protected override bool IsDragging => base.IsDragging || mouseScrollBarDragging;
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
protected override bool OnMouseDown(MouseDownEvent e)
{
if (shouldPerformRightMouseScroll(state))
if (shouldPerformRightMouseScroll(e))
{
scrollToRelative(state.Mouse.Position[ScrollDim]);
scrollToRelative(e.MousePosition[ScrollDim]);
return true;
}
return base.OnMouseDown(state, args);
return base.OnMouseDown(e);
}
protected override bool OnDrag(InputState state)
protected override bool OnDrag(DragEvent e)
{
if (mouseScrollBarDragging)
{
scrollToRelative(state.Mouse.Position[ScrollDim]);
scrollToRelative(e.MousePosition[ScrollDim]);
return true;
}
return base.OnDrag(state);
return base.OnDrag(e);
}
protected override bool OnDragStart(InputState state)
protected override bool OnDragStart(DragStartEvent e)
{
if (shouldPerformRightMouseScroll(state))
if (shouldPerformRightMouseScroll(e))
{
mouseScrollBarDragging = true;
return true;
}
return base.OnDragStart(state);
return base.OnDragStart(e);
}
protected override bool OnDragEnd(InputState state)
protected override bool OnDragEnd(DragEndEvent e)
{
if (mouseScrollBarDragging)
{
@ -69,7 +69,7 @@ namespace osu.Game.Graphics.Containers
return true;
}
return base.OnDragEnd(state);
return base.OnDragEnd(e);
}
}
}

View File

@ -1,7 +1,9 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Sprites;
@ -10,12 +12,15 @@ namespace osu.Game.Graphics.Containers
{
public class OsuTextFlowContainer : TextFlowContainer
{
public OsuTextFlowContainer(Action<SpriteText> defaultCreationParameters = null) : base(defaultCreationParameters)
public OsuTextFlowContainer(Action<SpriteText> defaultCreationParameters = null)
: base(defaultCreationParameters)
{
}
protected override SpriteText CreateSpriteText() => new OsuSpriteText();
public void AddIcon(FontAwesome icon, Action<SpriteText> creationParameters = null) => AddText(((char)icon).ToString(), creationParameters);
public void AddArbitraryDrawable(Drawable drawable) => AddInternal(drawable);
public IEnumerable<Drawable> AddIcon(IconUsage icon, Action<SpriteText> creationParameters = null) => AddText(icon.Icon.ToString(), creationParameters);
}
}

View File

@ -1,13 +1,13 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Framework.Input;
using OpenTK;
using osuTK;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Configuration;
using osu.Framework.Configuration;
using osu.Framework.MathUtils;
namespace osu.Game.Graphics.Containers
@ -16,6 +16,9 @@ namespace osu.Game.Graphics.Containers
{
public const float DEFAULT_PARALLAX_AMOUNT = 0.02f;
/// <summary>
/// The amount of parallax movement. Negative values will reverse the direction of parallax relative to user input.
/// </summary>
public float ParallaxAmount = DEFAULT_PARALLAX_AMOUNT;
private Bindable<bool> parallaxEnabled;
@ -42,10 +45,10 @@ namespace osu.Game.Graphics.Containers
parallaxEnabled = config.GetBindable<bool>(OsuSetting.MenuParallax);
parallaxEnabled.ValueChanged += delegate
{
if (!parallaxEnabled)
if (!parallaxEnabled.Value)
{
content.MoveTo(Vector2.Zero, firstUpdate ? 0 : 1000, Easing.OutQuint);
content.Scale = new Vector2(1 + ParallaxAmount);
content.Scale = new Vector2(1 + System.Math.Abs(ParallaxAmount));
}
};
}
@ -62,14 +65,14 @@ namespace osu.Game.Graphics.Containers
{
base.Update();
if (parallaxEnabled)
if (parallaxEnabled.Value)
{
Vector2 offset = (input.CurrentState.Mouse == null ? Vector2.Zero : ToLocalSpace(input.CurrentState.Mouse.NativeState.Position) - DrawSize / 2) * ParallaxAmount;
Vector2 offset = (input.CurrentState.Mouse == null ? Vector2.Zero : ToLocalSpace(input.CurrentState.Mouse.Position) - DrawSize / 2) * ParallaxAmount;
double elapsed = MathHelper.Clamp(Clock.ElapsedFrameTime, 0, 1000);
content.Position = Interpolation.ValueAt(elapsed, content.Position, offset, 0, 1000, Easing.OutQuint);
content.Scale = Interpolation.ValueAt(elapsed, content.Scale, new Vector2(1 + ParallaxAmount), 0, 1000, Easing.OutQuint);
content.Scale = Interpolation.ValueAt(elapsed, content.Scale, new Vector2(1 + System.Math.Abs(ParallaxAmount)), 0, 1000, Easing.OutQuint);
}
firstUpdate = false;

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;

View File

@ -0,0 +1,173 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Game.Configuration;
using osu.Game.Screens;
using osu.Game.Screens.Backgrounds;
using osuTK;
namespace osu.Game.Graphics.Containers
{
/// <summary>
/// Handles user-defined scaling, allowing application at multiple levels defined by <see cref="ScalingMode"/>.
/// </summary>
public class ScalingContainer : Container
{
private Bindable<float> sizeX;
private Bindable<float> sizeY;
private Bindable<float> posX;
private Bindable<float> posY;
private readonly ScalingMode? targetMode;
private Bindable<ScalingMode> scalingMode;
private readonly Container content;
protected override Container<Drawable> Content => content;
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
private readonly Container sizableContainer;
private BackgroundScreenStack backgroundStack;
/// <summary>
/// Create a new instance.
/// </summary>
/// <param name="targetMode">The mode which this container should be handling. Handles all modes if null.</param>
public ScalingContainer(ScalingMode? targetMode = null)
{
this.targetMode = targetMode;
RelativeSizeAxes = Axes.Both;
InternalChild = sizableContainer = new AlwaysInputContainer
{
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both,
CornerRadius = 10,
Child = content = new ScalingDrawSizePreservingFillContainer(targetMode != ScalingMode.Gameplay)
};
}
private class ScalingDrawSizePreservingFillContainer : DrawSizePreservingFillContainer
{
private readonly bool applyUIScale;
private Bindable<float> uiScale;
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
public ScalingDrawSizePreservingFillContainer(bool applyUIScale)
{
this.applyUIScale = applyUIScale;
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager osuConfig)
{
if (applyUIScale)
{
uiScale = osuConfig.GetBindable<float>(OsuSetting.UIScale);
uiScale.BindValueChanged(scaleChanged, true);
}
}
private void scaleChanged(ValueChangedEvent<float> args)
{
this.ScaleTo(new Vector2(args.NewValue), 500, Easing.Out);
this.ResizeTo(new Vector2(1 / args.NewValue), 500, Easing.Out);
}
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
scalingMode = config.GetBindable<ScalingMode>(OsuSetting.Scaling);
scalingMode.ValueChanged += _ => updateSize();
sizeX = config.GetBindable<float>(OsuSetting.ScalingSizeX);
sizeX.ValueChanged += _ => updateSize();
sizeY = config.GetBindable<float>(OsuSetting.ScalingSizeY);
sizeY.ValueChanged += _ => updateSize();
posX = config.GetBindable<float>(OsuSetting.ScalingPositionX);
posX.ValueChanged += _ => updateSize();
posY = config.GetBindable<float>(OsuSetting.ScalingPositionY);
posY.ValueChanged += _ => updateSize();
}
protected override void LoadComplete()
{
base.LoadComplete();
updateSize();
sizableContainer.FinishTransforms();
}
private bool requiresBackgroundVisible => (scalingMode.Value == ScalingMode.Everything || scalingMode.Value == ScalingMode.ExcludeOverlays) && (sizeX.Value != 1 || sizeY.Value != 1);
private void updateSize()
{
const float fade_time = 500;
if (targetMode == ScalingMode.Everything)
{
// the top level scaling container manages the background to be displayed while scaling.
if (requiresBackgroundVisible)
{
if (backgroundStack == null)
{
AddInternal(backgroundStack = new BackgroundScreenStack
{
Colour = OsuColour.Gray(0.1f),
Alpha = 0,
Depth = float.MaxValue
});
backgroundStack.Push(new ScalingBackgroundScreen());
}
backgroundStack.FadeIn(fade_time);
}
else
backgroundStack?.FadeOut(fade_time);
}
bool scaling = targetMode == null || scalingMode.Value == targetMode;
var targetSize = scaling ? new Vector2(sizeX.Value, sizeY.Value) : Vector2.One;
var targetPosition = scaling ? new Vector2(posX.Value, posY.Value) * (Vector2.One - targetSize) : Vector2.Zero;
bool requiresMasking = scaling && targetSize != Vector2.One;
if (requiresMasking)
sizableContainer.Masking = true;
sizableContainer.MoveTo(targetPosition, 500, Easing.OutQuart);
sizableContainer.ResizeTo(targetSize, 500, Easing.OutQuart).OnComplete(_ => { sizableContainer.Masking = requiresMasking; });
}
private class ScalingBackgroundScreen : BackgroundScreenDefault
{
public override void OnEntering(IScreen last)
{
this.FadeInFromZero(4000, Easing.OutQuint);
}
}
private class AlwaysInputContainer : Container
{
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
public AlwaysInputContainer()
{
RelativeSizeAxes = Axes.Both;
}
}
}
}

View File

@ -1,9 +1,9 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using System.Linq;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -24,7 +24,7 @@ namespace osu.Game.Graphics.Containers
public Drawable ExpandableHeader
{
get { return expandableHeader; }
get => expandableHeader;
set
{
if (value == expandableHeader) return;
@ -40,7 +40,7 @@ namespace osu.Game.Graphics.Containers
public Drawable FixedHeader
{
get { return fixedHeader; }
get => fixedHeader;
set
{
if (value == fixedHeader) return;
@ -56,7 +56,7 @@ namespace osu.Game.Graphics.Containers
public Drawable Footer
{
get { return footer; }
get => footer;
set
{
if (value == footer) return;
@ -75,7 +75,7 @@ namespace osu.Game.Graphics.Containers
public Drawable HeaderBackground
{
get { return headerBackground; }
get => headerBackground;
set
{
if (value == headerBackground) return;
@ -110,6 +110,7 @@ namespace osu.Game.Graphics.Containers
private float headerHeight, footerHeight;
private readonly MarginPadding originalSectionsMargin;
private void updateSectionsMargin()
{
if (!Children.Any()) return;
@ -141,13 +142,26 @@ namespace osu.Game.Graphics.Containers
public void ScrollToTop() => scrollContainer.ScrollTo(0);
public override void InvalidateFromChild(Invalidation invalidation, Drawable source = null)
{
base.InvalidateFromChild(invalidation, source);
if ((invalidation & Invalidation.DrawSize) != 0)
{
if (source == ExpandableHeader) //We need to recalculate the positions if the ExpandableHeader changed its size
lastKnownScroll = -1;
}
}
private float lastKnownScroll;
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
float headerH = (ExpandableHeader?.LayoutSize.Y ?? 0) + (FixedHeader?.LayoutSize.Y ?? 0);
float footerH = Footer?.LayoutSize.Y ?? 0;
if (headerH != headerHeight || footerH != footerHeight)
{
headerHeight = headerH;
@ -179,6 +193,7 @@ namespace osu.Game.Graphics.Containers
foreach (var section in Children)
{
float diff = Math.Abs(scrollContainer.GetChildPosInContent(section) - currentScroll - scrollOffset);
if (diff < minDiff)
{
minDiff = diff;

View File

@ -0,0 +1,53 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
namespace osu.Game.Graphics.Containers
{
/// <summary>
/// A container that adds the ability to shake its contents.
/// </summary>
public class ShakeContainer : Container
{
/// <summary>
/// The length of a single shake.
/// </summary>
public float ShakeDuration = 80;
/// <summary>
/// Total number of shakes. May be shortened if possible.
/// </summary>
public float TotalShakes = 4;
/// <summary>
/// Pixels of displacement per shake.
/// </summary>
public float ShakeMagnitude = 8;
/// <summary>
/// Shake the contents of this container.
/// </summary>
/// <param name="maximumLength">The maximum length the shake should last.</param>
public void Shake(double? maximumLength = null)
{
const float shake_amount = 8;
// if we don't have enough time, don't bother shaking.
if (maximumLength < ShakeDuration * 2)
return;
var sequence = this.MoveToX(shake_amount, ShakeDuration / 2, Easing.OutSine).Then()
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
// if we don't have enough time for the second shake, skip it.
if (!maximumLength.HasValue || maximumLength >= ShakeDuration * 4)
sequence = sequence
.MoveToX(shake_amount, ShakeDuration, Easing.InOutSine).Then()
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
sequence.MoveToX(0, ShakeDuration / 2, Easing.InSine);
}
}
}

View File

@ -0,0 +1,135 @@
// 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.Game.Configuration;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Screens.Play;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Graphics.Containers
{
/// <summary>
/// A container that applies user-configured visual settings to its contents.
/// This container specifies behavior that applies to both Storyboards and Backgrounds.
/// </summary>
public class UserDimContainer : Container
{
private const float background_fade_duration = 800;
/// <summary>
/// Whether or not user-configured dim levels should be applied to the container.
/// </summary>
public readonly Bindable<bool> EnableUserDim = new Bindable<bool>();
/// <summary>
/// Whether or not the storyboard loaded should completely hide the background behind it.
/// </summary>
public readonly Bindable<bool> StoryboardReplacesBackground = new Bindable<bool>();
/// <summary>
/// The amount of blur to be applied to the background in addition to user-specified blur.
/// </summary>
/// <remarks>
/// Used in contexts where there can potentially be both user and screen-specified blurring occuring at the same time, such as in <see cref="PlayerLoader"/>
/// </remarks>
public readonly Bindable<float> BlurAmount = new Bindable<float>();
private Bindable<double> userDimLevel { get; set; }
private Bindable<double> userBlurLevel { get; set; }
private Bindable<bool> showStoryboard { get; set; }
protected Container DimContainer { get; }
protected override Container<Drawable> Content => DimContainer;
private readonly bool isStoryboard;
/// <summary>
/// As an optimisation, we add the two blur portions to be applied rather than actually applying two separate blurs.
/// </summary>
private Vector2 blurTarget => EnableUserDim.Value
? new Vector2(BlurAmount.Value + (float)userBlurLevel.Value * 25)
: new Vector2(BlurAmount.Value);
/// <summary>
/// Creates a new <see cref="UserDimContainer"/>.
/// </summary>
/// <param name="isStoryboard"> Whether or not this instance contains a storyboard.
/// <remarks>
/// While both backgrounds and storyboards allow user dim levels to be applied, storyboards can be toggled via <see cref="showStoryboard"/>
/// and can cause backgrounds to become hidden via <see cref="StoryboardReplacesBackground"/>. Storyboards are also currently unable to be blurred.
/// </remarks>
/// </param>
public UserDimContainer(bool isStoryboard = false)
{
this.isStoryboard = isStoryboard;
AddInternal(DimContainer = new Container { RelativeSizeAxes = Axes.Both });
}
private Background background;
public Background Background
{
get => background;
set
{
base.Add(background = value);
background.BlurTo(blurTarget, 0, Easing.OutQuint);
}
}
public override void Add(Drawable drawable)
{
if (drawable is Background)
throw new InvalidOperationException($"Use {nameof(Background)} to set a background.");
base.Add(drawable);
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
userDimLevel = config.GetBindable<double>(OsuSetting.DimLevel);
userBlurLevel = config.GetBindable<double>(OsuSetting.BlurLevel);
showStoryboard = config.GetBindable<bool>(OsuSetting.ShowStoryboard);
EnableUserDim.ValueChanged += _ => updateVisuals();
userDimLevel.ValueChanged += _ => updateVisuals();
userBlurLevel.ValueChanged += _ => updateVisuals();
showStoryboard.ValueChanged += _ => updateVisuals();
StoryboardReplacesBackground.ValueChanged += _ => updateVisuals();
BlurAmount.ValueChanged += _ => updateVisuals();
}
protected override void LoadComplete()
{
base.LoadComplete();
updateVisuals();
}
private void updateVisuals()
{
if (isStoryboard)
{
DimContainer.FadeTo(!showStoryboard.Value || userDimLevel.Value == 1 ? 0 : 1, background_fade_duration, Easing.OutQuint);
}
else
{
// The background needs to be hidden in the case of it being replaced by the storyboard
DimContainer.FadeTo(showStoryboard.Value && StoryboardReplacesBackground.Value ? 0 : 1, background_fade_duration, Easing.OutQuint);
Background?.BlurTo(blurTarget, background_fade_duration, Easing.OutQuint);
}
DimContainer.FadeColour(EnableUserDim.Value ? OsuColour.Gray(1 - (float)userDimLevel.Value) : Color4.White, background_fade_duration, Easing.OutQuint);
}
}
}

View File

@ -1,12 +1,13 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using OpenTK.Graphics;
using osuTK.Graphics;
namespace osu.Game.Graphics.Containers
{

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;

View File

@ -1,19 +1,19 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using osuTK;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using osu.Game.Configuration;
using System;
using System.Diagnostics;
using JetBrains.Annotations;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Events;
using osuTK.Input;
namespace osu.Game.Graphics.Cursor
{
@ -22,12 +22,13 @@ namespace osu.Game.Graphics.Cursor
private readonly IBindable<bool> screenshotCursorVisibility = new Bindable<bool>(true);
public override bool IsPresent => screenshotCursorVisibility.Value && base.IsPresent;
protected override Drawable CreateCursor() => new Cursor();
protected override Drawable CreateCursor() => activeCursor = new Cursor();
private Cursor activeCursor;
private Bindable<bool> cursorRotate;
private bool dragging;
private bool startRotation;
private DragRotationState dragRotationState;
private Vector2 positionMouseDown;
[BackgroundDependencyLoader(true)]
private void load([NotNull] OsuConfigManager config, [CanBeNull] ScreenshotManager screenshotManager)
@ -38,83 +39,86 @@ namespace osu.Game.Graphics.Cursor
screenshotCursorVisibility.BindTo(screenshotManager.CursorVisibility);
}
protected override bool OnMouseMove(InputState state)
protected override bool OnMouseMove(MouseMoveEvent e)
{
if (cursorRotate && dragging)
if (dragRotationState != DragRotationState.NotDragging)
{
Debug.Assert(state.Mouse.PositionMouseDown != null);
var position = e.MousePosition;
var distance = Vector2Extensions.Distance(position, positionMouseDown);
// don't start rotating until we're moved a minimum distance away from the mouse down location,
// else it can have an annoying effect.
// ReSharper disable once PossibleInvalidOperationException
startRotation |= Vector2Extensions.Distance(state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30;
if (dragRotationState == DragRotationState.DragStarted && distance > 30)
dragRotationState = DragRotationState.Rotating;
if (startRotation)
// don't rotate when distance is zero to avoid NaN
if (dragRotationState == DragRotationState.Rotating && distance > 0)
{
Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value;
Vector2 offset = e.MousePosition - positionMouseDown;
float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f;
// Always rotate in the direction of least distance
float diff = (degrees - ActiveCursor.Rotation) % 360;
float diff = (degrees - activeCursor.Rotation) % 360;
if (diff < -180) diff += 360;
if (diff > 180) diff -= 360;
degrees = ActiveCursor.Rotation + diff;
degrees = activeCursor.Rotation + diff;
ActiveCursor.RotateTo(degrees, 600, Easing.OutQuint);
activeCursor.RotateTo(degrees, 600, Easing.OutQuint);
}
}
return base.OnMouseMove(state);
return base.OnMouseMove(e);
}
protected override bool OnDragStart(InputState state)
protected override bool OnMouseDown(MouseDownEvent e)
{
dragging = true;
return base.OnDragStart(state);
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
ActiveCursor.Scale = new Vector2(1);
ActiveCursor.ScaleTo(0.90f, 800, Easing.OutQuint);
((Cursor)ActiveCursor).AdditiveLayer.Alpha = 0;
((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero(800, Easing.OutQuint);
return base.OnMouseDown(state, args);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
if (!state.Mouse.HasMainButtonPressed)
// only trigger animation for main mouse buttons
if (e.Button <= MouseButton.Right)
{
dragging = false;
startRotation = false;
activeCursor.Scale = new Vector2(1);
activeCursor.ScaleTo(0.90f, 800, Easing.OutQuint);
((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, Easing.OutQuint);
ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), Easing.OutElasticHalf);
ActiveCursor.ScaleTo(1, 500, Easing.OutElastic);
activeCursor.AdditiveLayer.Alpha = 0;
activeCursor.AdditiveLayer.FadeInFromZero(800, Easing.OutQuint);
}
return base.OnMouseUp(state, args);
if (e.Button == MouseButton.Left && cursorRotate.Value)
{
dragRotationState = DragRotationState.DragStarted;
positionMouseDown = e.MousePosition;
}
return base.OnMouseDown(e);
}
protected override bool OnClick(InputState state)
protected override bool OnMouseUp(MouseUpEvent e)
{
((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint);
if (!e.IsPressed(MouseButton.Left) && !e.IsPressed(MouseButton.Right))
{
activeCursor.AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint);
activeCursor.ScaleTo(1, 500, Easing.OutElastic);
}
return base.OnClick(state);
if (e.Button == MouseButton.Left)
{
if (dragRotationState == DragRotationState.Rotating)
activeCursor.RotateTo(0, 600 * (1 + Math.Abs(activeCursor.Rotation / 720)), Easing.OutElasticHalf);
dragRotationState = DragRotationState.NotDragging;
}
return base.OnMouseUp(e);
}
protected override void PopIn()
{
ActiveCursor.FadeTo(1, 250, Easing.OutQuint);
ActiveCursor.ScaleTo(1, 400, Easing.OutQuint);
activeCursor.FadeTo(1, 250, Easing.OutQuint);
activeCursor.ScaleTo(1, 400, Easing.OutQuint);
}
protected override void PopOut()
{
ActiveCursor.FadeTo(0, 250, Easing.OutQuint);
ActiveCursor.ScaleTo(0.6f, 250, Easing.In);
activeCursor.FadeTo(0, 250, Easing.OutQuint);
activeCursor.ScaleTo(0.6f, 250, Easing.In);
}
public class Cursor : Container
@ -156,9 +160,16 @@ namespace osu.Game.Graphics.Cursor
};
cursorScale = config.GetBindable<double>(OsuSetting.MenuCursorSize);
cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2((float)newScale * base_scale);
cursorScale.ValueChanged += scale => cursorContainer.Scale = new Vector2((float)scale.NewValue * base_scale);
cursorScale.TriggerChange();
}
}
private enum DragRotationState
{
NotDragging,
DragStarted,
Rotating,
}
}
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System.Linq;
using osu.Framework.Graphics;
@ -43,6 +43,7 @@ namespace osu.Game.Graphics.Cursor
}
private IProvideCursor currentTarget;
protected override void Update()
{
base.Update();
@ -50,6 +51,7 @@ namespace osu.Game.Graphics.Cursor
if (!CanShowCursor)
{
currentTarget?.Cursor?.Hide();
currentTarget = null;
return;
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.UserInterface;

View File

@ -1,13 +1,13 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using OpenTK.Graphics;
using osuTK;
using osuTK.Graphics;
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.Game.Graphics.Sprites;
@ -17,10 +17,13 @@ namespace osu.Game.Graphics.Cursor
{
protected override ITooltip CreateTooltip() => new OsuTooltip();
public OsuTooltipContainer(CursorContainer cursor) : base(cursor)
public OsuTooltipContainer(CursorContainer cursor)
: base(cursor)
{
}
protected override double AppearDelay => (1 - CurrentTooltip.Alpha) * base.AppearDelay; // reduce appear delay if the tooltip is already partly visible.
public class OsuTooltip : Tooltip
{
private readonly Box background;
@ -34,6 +37,7 @@ namespace osu.Game.Graphics.Cursor
if (value == text.Text) return;
text.Text = value;
if (IsPresent)
{
AutoSizeDuration = 250;
@ -44,8 +48,6 @@ namespace osu.Game.Graphics.Cursor
}
}
private const float text_size = 16;
public OsuTooltip()
{
AutoSizeEasing = Easing.OutQuint;
@ -67,9 +69,8 @@ namespace osu.Game.Graphics.Cursor
},
text = new OsuSpriteText
{
TextSize = text_size,
Padding = new MarginPadding(5),
Font = @"Exo2.0-Regular",
Font = OsuFont.GetFont(weight: FontWeight.Regular)
}
};
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using Humanizer;
@ -12,14 +12,27 @@ namespace osu.Game.Graphics
{
public class DrawableDate : OsuSpriteText, IHasTooltip
{
private readonly DateTimeOffset date;
private DateTimeOffset date;
public DateTimeOffset Date
{
get => date;
set
{
if (date == value)
return;
date = value.ToLocalTime();
if (LoadState >= LoadState.Ready)
updateTime();
}
}
public DrawableDate(DateTimeOffset date)
{
AutoSizeAxes = Axes.Both;
Font = "Exo2.0-RegularItalic";
this.date = date.ToLocalTime();
Font = OsuFont.GetFont(weight: FontWeight.Regular, italics: true);
Date = date;
}
[BackgroundDependencyLoader]
@ -38,17 +51,19 @@ namespace osu.Game.Graphics
{
updateTime();
var diffToNow = DateTimeOffset.Now.Subtract(date);
var diffToNow = DateTimeOffset.Now.Subtract(Date);
double timeUntilNextUpdate = 1000;
if (diffToNow.TotalSeconds > 60)
if (Math.Abs(diffToNow.TotalSeconds) > 120)
{
timeUntilNextUpdate *= 60;
if (diffToNow.TotalMinutes > 60)
if (Math.Abs(diffToNow.TotalMinutes) > 120)
{
timeUntilNextUpdate *= 60;
if (diffToNow.TotalHours > 24)
if (Math.Abs(diffToNow.TotalHours) > 48)
timeUntilNextUpdate *= 24;
}
}
@ -56,10 +71,10 @@ namespace osu.Game.Graphics
Scheduler.AddDelayed(updateTimeWithReschedule, timeUntilNextUpdate);
}
public override bool HandleMouseInput => true;
protected virtual string Format() => Date.Humanize();
private void updateTime() => Text = date.Humanize();
private void updateTime() => Text = Format();
public string TooltipText => date.ToString();
public virtual string TooltipText => string.Format($"{Date:MMMM d, yyyy h:mm tt \"UTC\"z}");
}
}

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK.Graphics;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Transforms;

View File

@ -1,8 +1,8 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using OpenTK.Graphics;
using osuTK.Graphics;
namespace osu.Game.Graphics
{
@ -20,12 +20,14 @@ namespace osu.Game.Graphics
{
default:
throw new ArgumentException(@"Invalid hex string length!");
case 3:
return new Color4(
(byte)(Convert.ToByte(hex.Substring(0, 1), 16) * 17),
(byte)(Convert.ToByte(hex.Substring(1, 1), 16) * 17),
(byte)(Convert.ToByte(hex.Substring(2, 1), 16) * 17),
255);
case 6:
return new Color4(
Convert.ToByte(hex.Substring(0, 2), 16),
@ -66,6 +68,48 @@ namespace osu.Game.Graphics
public readonly Color4 GreenDark = FromHex(@"668800");
public readonly Color4 GreenDarker = FromHex(@"445500");
public readonly Color4 Sky = FromHex(@"6bb5ff");
public readonly Color4 GreySkyLighter = FromHex(@"c6e3f4");
public readonly Color4 GreySkyLight = FromHex(@"8ab3cc");
public readonly Color4 GreySky = FromHex(@"405461");
public readonly Color4 GreySkyDark = FromHex(@"303d47");
public readonly Color4 GreySkyDarker = FromHex(@"21272c");
public readonly Color4 Seafoam = FromHex(@"05ffa2");
public readonly Color4 GreySeafoamLighter = FromHex(@"9ebab1");
public readonly Color4 GreySeafoamLight = FromHex(@"4d7365");
public readonly Color4 GreySeafoam = FromHex(@"33413c");
public readonly Color4 GreySeafoamDark = FromHex(@"2c3532");
public readonly Color4 GreySeafoamDarker = FromHex(@"1e2422");
public readonly Color4 Cyan = FromHex(@"05f4fd");
public readonly Color4 GreyCyanLighter = FromHex(@"77b1b3");
public readonly Color4 GreyCyanLight = FromHex(@"436d6f");
public readonly Color4 GreyCyan = FromHex(@"293d3e");
public readonly Color4 GreyCyanDark = FromHex(@"243536");
public readonly Color4 GreyCyanDarker = FromHex(@"1e2929");
public readonly Color4 Lime = FromHex(@"82ff05");
public readonly Color4 GreyLimeLighter = FromHex(@"deff87");
public readonly Color4 GreyLimeLight = FromHex(@"657259");
public readonly Color4 GreyLime = FromHex(@"3f443a");
public readonly Color4 GreyLimeDark = FromHex(@"32352e");
public readonly Color4 GreyLimeDarker = FromHex(@"2e302b");
public readonly Color4 Violet = FromHex(@"bf04ff");
public readonly Color4 GreyVioletLighter = FromHex(@"ebb8fe");
public readonly Color4 GreyVioletLight = FromHex(@"685370");
public readonly Color4 GreyViolet = FromHex(@"46334d");
public readonly Color4 GreyVioletDark = FromHex(@"2c2230");
public readonly Color4 GreyVioletDarker = FromHex(@"201823");
public readonly Color4 Carmine = FromHex(@"ff0542");
public readonly Color4 GreyCarmineLighter = FromHex(@"deaab4");
public readonly Color4 GreyCarmineLight = FromHex(@"644f53");
public readonly Color4 GreyCarmine = FromHex(@"342b2d");
public readonly Color4 GreyCarmineDark = FromHex(@"302a2b");
public readonly Color4 GreyCarmineDarker = FromHex(@"241d1e");
public readonly Color4 Gray0 = FromHex(@"000");
public readonly Color4 Gray1 = FromHex(@"111");
public readonly Color4 Gray2 = FromHex(@"222");
@ -92,5 +136,15 @@ namespace osu.Game.Graphics
public readonly Color4 ChatBlue = FromHex(@"17292e");
public readonly Color4 ContextMenuGray = FromHex(@"223034");
public readonly Color4 CommunityUserGreenLight = FromHex(@"deff87");
public readonly Color4 CommunityUserGreen = FromHex(@"05ffa2");
public readonly Color4 CommunityUserGreenDark = FromHex(@"a6cc00");
public readonly Color4 CommunityUserGrayGreenLighter = FromHex(@"9ebab1");
public readonly Color4 CommunityUserGrayGreenLight = FromHex(@"77998e");
public readonly Color4 CommunityUserGrayGreen = FromHex(@"4e7466");
public readonly Color4 CommunityUserGrayGreenDark = FromHex(@"33413c");
public readonly Color4 CommunityUserGrayGreenDarker = FromHex(@"2c3532");
public readonly Color4 CommunityUserGrayGreenDarkest = FromHex(@"1e2422");
}
}

View File

@ -0,0 +1,116 @@
// 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.Sprites;
namespace osu.Game.Graphics
{
public static class OsuFont
{
/// <summary>
/// The default font size.
/// </summary>
public const float DEFAULT_FONT_SIZE = 16;
/// <summary>
/// The default font.
/// </summary>
public static FontUsage Default => GetFont();
public static FontUsage Numeric => GetFont(Typeface.Venera, weight: FontWeight.Regular);
/// <summary>
/// Retrieves a <see cref="FontUsage"/>.
/// </summary>
/// <param name="typeface">The font typeface.</param>
/// <param name="size">The size of the text in local space. For a value of 16, a single line will have a height of 16px.</param>
/// <param name="weight">The font weight.</param>
/// <param name="italics">Whether the font is italic.</param>
/// <param name="fixedWidth">Whether all characters should be spaced the same distance apart.</param>
/// <returns>The <see cref="FontUsage"/>.</returns>
public static FontUsage GetFont(Typeface typeface = Typeface.Exo, float size = DEFAULT_FONT_SIZE, FontWeight weight = FontWeight.Medium, bool italics = false, bool fixedWidth = false)
=> new FontUsage(GetFamilyString(typeface), size, GetWeightString(typeface, weight), italics, fixedWidth);
/// <summary>
/// Retrieves the string representation of a <see cref="Typeface"/>.
/// </summary>
/// <param name="typeface">The <see cref="Typeface"/>.</param>
/// <returns>The string representation.</returns>
public static string GetFamilyString(Typeface typeface)
{
switch (typeface)
{
case Typeface.Exo:
return "Exo2.0";
case Typeface.Venera:
return "Venera";
}
return null;
}
/// <summary>
/// Retrieves the string representation of a <see cref="FontWeight"/>.
/// </summary>
/// <param name="typeface">The <see cref="Typeface"/>.</param>
/// <param name="weight">The <see cref="FontWeight"/>.</param>
/// <returns>The string representation of <paramref name="weight"/> in the specified <paramref name="typeface"/>.</returns>
public static string GetWeightString(Typeface typeface, FontWeight weight)
=> GetWeightString(GetFamilyString(typeface), weight);
/// <summary>
/// Retrieves the string representation of a <see cref="FontWeight"/>.
/// </summary>
/// <param name="family">The family string.</param>
/// <param name="weight">The <see cref="FontWeight"/>.</param>
/// <returns>The string representation of <paramref name="weight"/> in the specified <paramref name="family"/>.</returns>
public static string GetWeightString(string family, FontWeight weight)
{
string weightString = weight.ToString();
// Only exo has an explicit "regular" weight, other fonts do not
if (family != GetFamilyString(Typeface.Exo) && weight == FontWeight.Regular)
weightString = string.Empty;
return weightString;
}
}
public static class OsuFontExtensions
{
/// <summary>
/// Creates a new <see cref="FontUsage"/> by applying adjustments to this <see cref="FontUsage"/>.
/// </summary>
/// <param name="usage">The base <see cref="FontUsage"/>.</param>
/// <param name="typeface">The font typeface. If null, the value is copied from this <see cref="FontUsage"/>.</param>
/// <param name="size">The text size. If null, the value is copied from this <see cref="FontUsage"/>.</param>
/// <param name="weight">The font weight. If null, the value is copied from this <see cref="FontUsage"/>.</param>
/// <param name="italics">Whether the font is italic. If null, the value is copied from this <see cref="FontUsage"/>.</param>
/// <param name="fixedWidth">Whether all characters should be spaced apart the same distance. If null, the value is copied from this <see cref="FontUsage"/>.</param>
/// <returns>The resulting <see cref="FontUsage"/>.</returns>
public static FontUsage With(this FontUsage usage, Typeface? typeface = null, float? size = null, FontWeight? weight = null, bool? italics = null, bool? fixedWidth = null)
{
string familyString = typeface != null ? OsuFont.GetFamilyString(typeface.Value) : usage.Family;
string weightString = weight != null ? OsuFont.GetWeightString(familyString, weight.Value) : usage.Weight;
return usage.With(familyString, size, weightString, italics, fixedWidth);
}
}
public enum Typeface
{
Exo,
Venera,
}
public enum FontWeight
{
Light,
Regular,
Medium,
SemiBold,
Bold,
Black
}
}

View File

@ -0,0 +1,94 @@
// 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.Sprites;
namespace osu.Game.Graphics
{
public static class OsuIcon
{
public static IconUsage Get(int icon) => new IconUsage((char)icon, "osuFont");
// ruleset icons in circles
public static IconUsage RulesetOsu => Get(0xe000);
public static IconUsage RulesetMania => Get(0xe001);
public static IconUsage RulesetCatch => Get(0xe002);
public static IconUsage RulesetTaiko => Get(0xe003);
// ruleset icons without circles
public static IconUsage FilledCircle => Get(0xe004);
public static IconUsage CrossCircle => Get(0xe005);
public static IconUsage Logo => Get(0xe006);
public static IconUsage ChevronDownCircle => Get(0xe007);
public static IconUsage EditCircle => Get(0xe033);
public static IconUsage LeftCircle => Get(0xe034);
public static IconUsage RightCircle => Get(0xe035);
public static IconUsage Charts => Get(0xe036);
public static IconUsage Solo => Get(0xe037);
public static IconUsage Multi => Get(0xe038);
public static IconUsage Gear => Get(0xe039);
// misc icons
public static IconUsage Bat => Get(0xe008);
public static IconUsage Bubble => Get(0xe009);
public static IconUsage BubblePop => Get(0xe02e);
public static IconUsage Dice => Get(0xe011);
public static IconUsage Heart => Get(0xe02f);
public static IconUsage HeartBreak => Get(0xe030);
public static IconUsage Hot => Get(0xe031);
public static IconUsage ListSearch => Get(0xe032);
//osu! playstyles
public static IconUsage PlaystyleTablet => Get(0xe02a);
public static IconUsage PlaystyleMouse => Get(0xe029);
public static IconUsage PlaystyleKeyboard => Get(0xe02b);
public static IconUsage PlaystyleTouch => Get(0xe02c);
// osu! difficulties
public static IconUsage EasyOsu => Get(0xe015);
public static IconUsage NormalOsu => Get(0xe016);
public static IconUsage HardOsu => Get(0xe017);
public static IconUsage InsaneOsu => Get(0xe018);
public static IconUsage ExpertOsu => Get(0xe019);
// taiko difficulties
public static IconUsage EasyTaiko => Get(0xe01a);
public static IconUsage NormalTaiko => Get(0xe01b);
public static IconUsage HardTaiko => Get(0xe01c);
public static IconUsage InsaneTaiko => Get(0xe01d);
public static IconUsage ExpertTaiko => Get(0xe01e);
// fruits difficulties
public static IconUsage EasyFruits => Get(0xe01f);
public static IconUsage NormalFruits => Get(0xe020);
public static IconUsage HardFruits => Get(0xe021);
public static IconUsage InsaneFruits => Get(0xe022);
public static IconUsage ExpertFruits => Get(0xe023);
// mania difficulties
public static IconUsage EasyMania => Get(0xe024);
public static IconUsage NormalMania => Get(0xe025);
public static IconUsage HardMania => Get(0xe026);
public static IconUsage InsaneMania => Get(0xe027);
public static IconUsage ExpertMania => Get(0xe028);
// mod icons
public static IconUsage ModPerfect => Get(0xe049);
public static IconUsage ModAutopilot => Get(0xe03a);
public static IconUsage ModAuto => Get(0xe03b);
public static IconUsage ModCinema => Get(0xe03c);
public static IconUsage ModDoubletime => Get(0xe03d);
public static IconUsage ModEasy => Get(0xe03e);
public static IconUsage ModFlashlight => Get(0xe03f);
public static IconUsage ModHalftime => Get(0xe040);
public static IconUsage ModHardrock => Get(0xe041);
public static IconUsage ModHidden => Get(0xe042);
public static IconUsage ModNightcore => Get(0xe043);
public static IconUsage ModNofail => Get(0xe044);
public static IconUsage ModRelax => Get(0xe045);
public static IconUsage ModSpunout => Get(0xe046);
public static IconUsage ModSuddendeath => Get(0xe047);
public static IconUsage ModTarget => Get(0xe048);
public static IconUsage ModBg => Get(0xe04a);
}
}

View File

@ -1,15 +1,14 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
@ -19,6 +18,7 @@ using osu.Game.Configuration;
using osu.Game.Input.Bindings;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using SixLabors.ImageSharp;
namespace osu.Game.Graphics
{
@ -71,7 +71,7 @@ namespace osu.Game.Graphics
private volatile int screenShotTasks;
public async Task TakeScreenshotAsync() => await Task.Run(async () =>
public Task TakeScreenshotAsync() => Task.Run(async () =>
{
Interlocked.Increment(ref screenShotTasks);
@ -90,7 +90,7 @@ namespace osu.Game.Graphics
waitDelegate.Cancel();
}
using (var bitmap = await host.TakeScreenshotAsync())
using (var image = await host.TakeScreenshotAsync())
{
Interlocked.Decrement(ref screenShotTasks);
@ -102,11 +102,13 @@ namespace osu.Game.Graphics
switch (screenshotFormat.Value)
{
case ScreenshotFormat.Png:
bitmap.Save(stream, ImageFormat.Png);
image.SaveAsPng(stream);
break;
case ScreenshotFormat.Jpg:
bitmap.Save(stream, ImageFormat.Jpeg);
image.SaveAsJpeg(stream);
break;
default:
throw new ArgumentOutOfRangeException(nameof(screenshotFormat));
}
@ -127,14 +129,14 @@ namespace osu.Game.Graphics
{
base.Update();
if (cursorVisibility == false && Interlocked.CompareExchange(ref screenShotTasks, 0, 0) == 0)
if (cursorVisibility.Value == false && Interlocked.CompareExchange(ref screenShotTasks, 0, 0) == 0)
cursorVisibility.Value = true;
}
private string getFileName()
{
var dt = DateTime.Now;
var fileExt = screenshotFormat.ToString().ToLower();
var fileExt = screenshotFormat.ToString().ToLowerInvariant();
var withoutIndex = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}.{fileExt}";
if (!storage.Exists(withoutIndex))

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +1,18 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Transforms;
namespace osu.Game.Graphics.Sprites
{
public class OsuSpriteText : SpriteText
{
public const float FONT_SIZE = 16;
public OsuSpriteText()
{
Shadow = true;
TextSize = FONT_SIZE;
}
protected override Drawable CreateFallbackCharacterDrawable()
{
var tex = GetTextureForCharacter('?');
if (tex != null)
{
float adjust = (RNG.NextSingle() - 0.5f) * 2;
return new Sprite
{
Texture = tex,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Scale = new Vector2(1 + adjust * 0.2f),
Rotation = adjust * 15,
Colour = Color4.White,
};
}
return base.CreateFallbackCharacterDrawable();
Font = OsuFont.Default;
}
}

View File

@ -1,18 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores;
namespace osu.Game.Graphics.Textures
{
/// <summary>
/// A texture store that bypasses atlasing.
/// </summary>
public class LargeTextureStore : TextureStore
{
public LargeTextureStore(IResourceStore<RawTexture> store = null) : base(store, false)
{
}
}
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@ -11,7 +11,7 @@ namespace osu.Game.Graphics.UserInterface
public BackButton()
{
Text = @"back";
Icon = FontAwesome.fa_osu_left_o;
Icon = OsuIcon.LeftCircle;
Anchor = Anchor.BottomLeft;
Origin = Anchor.BottomLeft;
}

View File

@ -1,8 +1,8 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using OpenTK.Graphics;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -26,10 +26,7 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public float Length
{
get
{
return length;
}
get => length;
set
{
length = MathHelper.Clamp(value, 0, 1);
@ -39,35 +36,21 @@ namespace osu.Game.Graphics.UserInterface
public Color4 BackgroundColour
{
get
{
return background.Colour;
}
set
{
background.Colour = value;
}
get => background.Colour;
set => background.Colour = value;
}
public Color4 AccentColour
{
get
{
return bar.Colour;
}
set
{
bar.Colour = value;
}
get => bar.Colour;
set => bar.Colour = value;
}
private BarDirection direction = BarDirection.LeftToRight;
public BarDirection Direction
{
get
{
return direction;
}
get => direction;
set
{
direction = value;

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using osuTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using System.Collections.Generic;
@ -17,19 +17,18 @@ namespace osu.Game.Graphics.UserInterface
public float? MaxValue { get; set; }
private BarDirection direction = BarDirection.BottomToTop;
public new BarDirection Direction
{
get
{
return direction;
}
get => direction;
set
{
direction = value;
base.Direction = (direction & BarDirection.Horizontal) > 0 ? FillDirection.Vertical : FillDirection.Horizontal;
base.Direction = direction.HasFlag(BarDirection.Horizontal) ? FillDirection.Vertical : FillDirection.Horizontal;
foreach (var bar in Children)
{
bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / Children.Count) : new Vector2(1.0f / Children.Count, 1);
bar.Size = direction.HasFlag(BarDirection.Horizontal) ? new Vector2(1, 1.0f / Children.Count) : new Vector2(1.0f / Children.Count, 1);
bar.Direction = direction;
}
}
@ -43,6 +42,7 @@ namespace osu.Game.Graphics.UserInterface
set
{
List<Bar> bars = Children.ToList();
foreach (var bar in value.Select((length, index) => new { Value = length, Bar = bars.Count > index ? bars[index] : null }))
{
float length = MaxValue ?? value.Max();
@ -56,19 +56,20 @@ namespace osu.Game.Graphics.UserInterface
if (bar.Bar != null)
{
bar.Bar.Length = length;
bar.Bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, size) : new Vector2(size, 1);
bar.Bar.Size = direction.HasFlag(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1);
}
else
{
Add(new Bar
{
RelativeSizeAxes = Axes.Both,
Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, size) : new Vector2(size, 1),
Size = direction.HasFlag(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1),
Length = length,
Direction = Direction,
});
}
}
//I'm using ToList() here because Where() returns an Enumerable which can change it's elements afterwards
RemoveRange(Children.Where((bar, index) => index >= value.Count()).ToList());
}

View File

@ -1,13 +1,14 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using OpenTK;
using osuTK;
using osu.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using System.Linq;
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface
{
@ -27,12 +28,12 @@ namespace osu.Game.Graphics.UserInterface
{
Height = 32;
TabContainer.Spacing = new Vector2(padding, 0f);
Current.ValueChanged += tab =>
Current.ValueChanged += index =>
{
foreach (var t in TabContainer.Children.OfType<BreadcrumbTabItem>())
{
var tIndex = TabContainer.IndexOf(t);
var tabIndex = TabContainer.IndexOf(TabMap[tab]);
var tabIndex = TabContainer.IndexOf(TabMap[index.NewValue]);
t.State = tIndex < tabIndex ? Visibility.Hidden : Visibility.Visible;
t.Chevron.FadeTo(tIndex <= tabIndex ? 0f : 1f, 500, Easing.OutQuint);
@ -47,20 +48,21 @@ namespace osu.Game.Graphics.UserInterface
public readonly SpriteIcon Chevron;
//don't allow clicking between transitions and don't make the chevron clickable
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => Alpha == 1f && Text.ReceiveMouseInputAt(screenSpacePos);
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Alpha == 1f && Text.ReceivePositionalInputAt(screenSpacePos);
public override bool HandleKeyboardInput => State == Visibility.Visible;
public override bool HandleMouseInput => State == Visibility.Visible;
public override bool HandleNonPositionalInput => State == Visibility.Visible;
public override bool HandlePositionalInput => State == Visibility.Visible;
public override bool IsRemovable => true;
private Visibility state;
public Visibility State
{
get { return state; }
get => state;
set
{
if (value == state) return;
state = value;
const float transition_duration = 500;
@ -80,9 +82,10 @@ namespace osu.Game.Graphics.UserInterface
}
}
public BreadcrumbTabItem(T value) : base(value)
public BreadcrumbTabItem(T value)
: base(value)
{
Text.TextSize = 18;
Text.Font = Text.Font.With(size: 18);
Text.Margin = new MarginPadding { Vertical = 8 };
Padding = new MarginPadding { Right = padding + item_chevron_size };
Add(Chevron = new SpriteIcon
@ -90,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreLeft,
Size = new Vector2(item_chevron_size),
Icon = FontAwesome.fa_chevron_right,
Icon = FontAwesome.Solid.ChevronRight,
Margin = new MarginPadding { Left = padding },
Alpha = 0f,
});

View File

@ -1,8 +1,9 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Bindables;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Shapes;
@ -11,9 +12,9 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics.Effects;
using osu.Game.Graphics.Containers;
using osu.Framework.Configuration;
using osu.Framework.Input;
using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
{
@ -141,8 +142,7 @@ namespace osu.Game.Graphics.UserInterface
Text = Text,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
TextSize = 28,
Font = "Exo2.0-Bold",
Font = OsuFont.GetFont(size: 28, weight: FontWeight.Bold),
Shadow = true,
ShadowColour = new Color4(0, 0, 0, 0.1f),
Colour = Color4.White,
@ -155,12 +155,10 @@ namespace osu.Game.Graphics.UserInterface
}
private Color4 buttonColour;
public Color4 ButtonColour
{
get
{
return buttonColour;
}
get => buttonColour;
set
{
buttonColour = value;
@ -170,12 +168,10 @@ namespace osu.Game.Graphics.UserInterface
}
private Color4 backgroundColour = OsuColour.Gray(34);
public Color4 BackgroundColour
{
get
{
return backgroundColour;
}
get => backgroundColour;
set
{
backgroundColour = value;
@ -184,12 +180,10 @@ namespace osu.Game.Graphics.UserInterface
}
private string text;
public string Text
{
get
{
return text;
}
get => text;
set
{
text = value;
@ -197,23 +191,15 @@ namespace osu.Game.Graphics.UserInterface
}
}
private float textSize = 28;
public float TextSize
{
get
{
return textSize;
}
set
{
textSize = value;
spriteText.TextSize = value;
}
get => spriteText.Font.Size;
set => spriteText.Font = spriteText.Font.With(size: value);
}
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => backgroundContainer.ReceiveMouseInputAt(screenSpacePos);
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => backgroundContainer.ReceivePositionalInputAt(screenSpacePos);
protected override bool OnClick(InputState state)
protected override bool OnClick(ClickEvent e)
{
colourContainer.ResizeTo(new Vector2(1.5f, 1f), click_duration, Easing.In);
flash();
@ -225,26 +211,26 @@ namespace osu.Game.Graphics.UserInterface
glowContainer.FadeOut();
});
return base.OnClick(state);
return base.OnClick(e);
}
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
base.OnHover(state);
base.OnHover(e);
Selected.Value = true;
return true;
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
base.OnHoverLost(state);
base.OnHoverLost(e);
Selected.Value = false;
}
private void selectionChanged(bool isSelected)
private void selectionChanged(ValueChangedEvent<bool> args)
{
if (isSelected)
if (args.NewValue)
{
spriteText.TransformSpacingTo(hoverSpacing, hover_duration, Easing.OutElastic);
colourContainer.ResizeTo(new Vector2(hover_width, 1f), hover_duration, Easing.OutElastic);

View File

@ -1,14 +1,15 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Input;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Platform;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
@ -17,6 +18,7 @@ namespace osu.Game.Graphics.UserInterface
public string Link { get; set; }
private Color4 hoverColour;
private GameHost host;
public ExternalLinkButton(string link = null)
{
@ -24,37 +26,34 @@ namespace osu.Game.Graphics.UserInterface
Size = new Vector2(12);
InternalChild = new SpriteIcon
{
Icon = FontAwesome.fa_external_link,
Icon = FontAwesome.Solid.ExternalLinkAlt,
RelativeSizeAxes = Axes.Both
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, GameHost host)
{
hoverColour = colours.Yellow;
this.host = host;
}
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
InternalChild.FadeColour(hoverColour, 500, Easing.OutQuint);
return base.OnHover(state);
return base.OnHover(e);
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
InternalChild.FadeColour(Color4.White, 500, Easing.OutQuint);
base.OnHoverLost(state);
base.OnHoverLost(e);
}
protected override bool OnClick(InputState state)
protected override bool OnClick(ClickEvent e)
{
if(Link != null)
Process.Start(new ProcessStartInfo
{
FileName = Link,
UseShellExecute = true //see https://github.com/dotnet/corefx/issues/10361
});
if (Link != null)
host.OpenUrlExternally(Link);
return true;
}

View File

@ -1,10 +1,13 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK.Graphics;
using OpenTK.Input;
using osu.Framework.Input;
using osuTK.Graphics;
using System;
using osu.Framework.Allocation;
using osu.Framework.Input.Events;
using osu.Framework.Platform;
using osu.Game.Input.Bindings;
using osuTK.Input;
namespace osu.Game.Graphics.UserInterface
{
@ -13,44 +16,76 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public class FocusedTextBox : OsuTextBox
{
protected override Color4 BackgroundUnfocused => new Color4(10, 10, 10, 255);
protected override Color4 BackgroundFocused => new Color4(10, 10, 10, 255);
public Action Exit;
private bool focus;
private bool allowImmediateFocus => host?.OnScreenKeyboardOverlapsGameWindow != true;
public void TakeFocus()
{
if (allowImmediateFocus) GetContainingInputManager().ChangeFocus(this);
}
public bool HoldFocus
{
get { return focus; }
get => allowImmediateFocus && focus;
set
{
focus = value;
if (!focus && HasFocus)
GetContainingInputManager().ChangeFocus(null);
base.KillFocus();
}
}
private GameHost host;
[BackgroundDependencyLoader]
private void load(GameHost host)
{
this.host = host;
BackgroundUnfocused = new Color4(10, 10, 10, 255);
BackgroundFocused = new Color4(10, 10, 10, 255);
}
// We may not be focused yet, but we need to handle keyboard input to be able to request focus
public override bool HandleKeyboardInput => HoldFocus || base.HandleKeyboardInput;
public override bool HandleNonPositionalInput => HoldFocus || base.HandleNonPositionalInput;
protected override void OnFocus(InputState state)
protected override void OnFocus(FocusEvent e)
{
base.OnFocus(state);
base.OnFocus(e);
BorderThickness = 0;
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
protected override bool OnKeyDown(KeyDownEvent e)
{
if (!args.Repeat && args.Key == Key.Escape)
if (!HasFocus) return false;
if (e.Key == Key.Escape)
return false; // disable the framework-level handling of escape key for confority (we use GlobalAction.Back).
return base.OnKeyDown(e);
}
public override bool OnPressed(GlobalAction action)
{
if (action == GlobalAction.Back)
{
if (Text.Length > 0)
{
Text = string.Empty;
else
Exit?.Invoke();
return true;
return true;
}
}
return base.OnKeyDown(state, args);
return base.OnPressed(action);
}
protected override void KillFocus()
{
base.KillFocus();
Exit?.Invoke();
}
public override bool RequestsFocus => HoldFocus;

View File

@ -1,11 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Extensions;
using osu.Framework.Input;
using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
{
@ -17,14 +17,15 @@ namespace osu.Game.Graphics.UserInterface
{
private SampleChannel sampleClick;
public HoverClickSounds(HoverSampleSet sampleSet = HoverSampleSet.Normal) : base(sampleSet)
public HoverClickSounds(HoverSampleSet sampleSet = HoverSampleSet.Normal)
: base(sampleSet)
{
}
protected override bool OnClick(InputState state)
protected override bool OnClick(ClickEvent e)
{
sampleClick?.Play();
return base.OnClick(state);
return base.OnClick(e);
}
[BackgroundDependencyLoader]

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System.ComponentModel;
using osu.Framework.Allocation;
@ -8,7 +8,7 @@ using osu.Framework.Audio.Sample;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
{
@ -28,10 +28,10 @@ namespace osu.Game.Graphics.UserInterface
RelativeSizeAxes = Axes.Both;
}
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
sampleHover?.Play();
return base.OnHover(state);
return base.OnHover(e);
}
[BackgroundDependencyLoader]
@ -45,8 +45,10 @@ namespace osu.Game.Graphics.UserInterface
{
[Description("")]
Loud,
[Description("-soft")]
Normal,
[Description("-softer")]
Soft
}

View File

@ -1,39 +1,26 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Game.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
{
public class IconButton : OsuClickableContainer
public class IconButton : OsuAnimatedButton
{
public const float BUTTON_SIZE = 30;
private Color4? flashColour;
/// <summary>
/// The colour that should be flashed when the <see cref="IconButton"/> is clicked.
/// </summary>
public Color4 FlashColour
{
get { return flashColour ?? Color4.White; }
set { flashColour = value; }
}
private Color4? iconColour;
/// <summary>
/// The icon colour. This does not affect <see cref="IconButton.Colour"/>.
/// </summary>
public Color4 IconColour
{
get { return iconColour ?? Color4.White; }
get => iconColour ?? Color4.White;
set
{
iconColour = value;
@ -42,36 +29,23 @@ namespace osu.Game.Graphics.UserInterface
}
private Color4? iconHoverColour;
/// <summary>
/// The icon colour while the <see cref="IconButton"/> is hovered.
/// </summary>
public Color4 IconHoverColour
{
get { return iconHoverColour ?? IconColour; }
set { iconHoverColour = value; }
}
private Color4? hoverColour;
/// <summary>
/// The background colour of the <see cref="IconButton"/> while it is hovered.
/// </summary>
public Color4 HoverColour
{
get { return hoverColour ?? Color4.White; }
set
{
hoverColour = value;
hover.Colour = value;
}
get => iconHoverColour ?? IconColour;
set => iconHoverColour = value;
}
/// <summary>
/// The icon.
/// </summary>
public FontAwesome Icon
public IconUsage Icon
{
get { return icon.Icon; }
set { icon.Icon = value; }
get => icon.Icon;
set => icon.Icon = value;
}
/// <summary>
@ -79,8 +53,8 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public Vector2 IconScale
{
get { return icon.Scale; }
set { icon.Scale = value; }
get => icon.Scale;
set => icon.Scale = value;
}
/// <summary>
@ -88,93 +62,39 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public Vector2 ButtonSize
{
get { return content.Size; }
set { content.Size = value; }
get => Content.Size;
set
{
Content.RelativeSizeAxes = Axes.None;
Content.Size = value;
}
}
private readonly Container content;
private readonly SpriteIcon icon;
private readonly Box hover;
public IconButton()
{
AutoSizeAxes = Axes.Both;
ButtonSize = new Vector2(BUTTON_SIZE);
Children = new Drawable[]
Add(icon = new SpriteIcon
{
content = new Container
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(BUTTON_SIZE),
CornerRadius = 5,
Masking = true,
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0.04f),
Type = EdgeEffectType.Shadow,
Radius = 5,
},
Children = new Drawable[]
{
hover = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
},
icon = new SpriteIcon
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(18),
}
}
}
};
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(18),
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
protected override bool OnHover(HoverEvent e)
{
if (hoverColour == null)
HoverColour = colours.Yellow.Opacity(0.6f);
if (flashColour == null)
FlashColour = colours.Yellow;
Enabled.ValueChanged += enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint);
}
protected override bool OnHover(InputState state)
{
hover.FadeIn(500, Easing.OutQuint);
icon.FadeColour(IconHoverColour, 500, Easing.OutQuint);
return base.OnHover(state);
return base.OnHover(e);
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
hover.FadeOut(500, Easing.OutQuint);
icon.FadeColour(IconColour, 500, Easing.OutQuint);
base.OnHoverLost(state);
}
protected override bool OnClick(InputState state)
{
hover.FlashColour(FlashColour, 800, Easing.OutQuint);
return base.OnClick(state);
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
content.ScaleTo(0.75f, 2000, Easing.OutQuint);
return base.OnMouseDown(state, args);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
content.ScaleTo(1, 1000, Easing.OutElastic);
return base.OnMouseUp(state, args);
base.OnHoverLost(e);
}
}
}

View File

@ -1,14 +1,15 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Caching;
using OpenTK;
using osuTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Lines;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
@ -44,7 +45,7 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public IEnumerable<float> Values
{
get { return values; }
get => values;
set
{
values = value.ToArray();
@ -63,13 +64,19 @@ namespace osu.Game.Graphics.UserInterface
}
}
public Color4 LineColour
{
get => maskingContainer.Colour;
set => maskingContainer.Colour = value;
}
public LineGraph()
{
Add(maskingContainer = new Container<Path>
{
Masking = true,
RelativeSizeAxes = Axes.Both,
Child = path = new Path { RelativeSizeAxes = Axes.Both, PathWidth = 1 }
Child = path = new SmoothPath { RelativeSizeAxes = Axes.Both, PathRadius = 1 }
});
}
@ -86,6 +93,7 @@ namespace osu.Game.Graphics.UserInterface
protected override void Update()
{
base.Update();
if (!pathCached.IsValid)
{
applyPath();
@ -102,9 +110,10 @@ namespace osu.Game.Graphics.UserInterface
for (int i = 0; i < values.Length; i++)
{
float x = (i + count - values.Length) / (float)(count - 1) * DrawWidth - 1;
float y = GetYPosition(values[i]) * DrawHeight - 1;
// the -1 is for inner offset in path (actually -PathWidth)
// Make sure that we are accounting for path width when calculating vertex positions
// We need to apply 2x the path radius to account for it because the full diameter of the line accounts into height
float x = (i + count - values.Length) / (float)(count - 1) * (DrawWidth - 2 * path.PathRadius);
float y = GetYPosition(values[i]) * (DrawHeight - 2 * path.PathRadius);
path.AddVertex(new Vector2(x, y));
}
}
@ -112,6 +121,7 @@ namespace osu.Game.Graphics.UserInterface
protected float GetYPosition(float value)
{
if (ActualMaxValue == ActualMinValue) return 0;
return (ActualMaxValue - value) / (ActualMaxValue - ActualMinValue);
}
}

View File

@ -1,15 +1,24 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using OpenTK;
using osu.Framework.Graphics.Sprites;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
/// <summary>
/// A loading spinner.
/// </summary>
public class LoadingAnimation : VisibilityContainer
{
private readonly SpriteIcon spinner;
private readonly SpriteIcon spinnerShadow;
private const float spin_duration = 600;
private const float transition_duration = 200;
public LoadingAnimation()
{
@ -20,12 +29,22 @@ namespace osu.Game.Graphics.UserInterface
Children = new Drawable[]
{
spinner = new SpriteIcon
spinnerShadow = new SpriteIcon
{
Size = new Vector2(20),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.fa_spinner
RelativeSizeAxes = Axes.Both,
Position = new Vector2(1, 1),
Colour = Color4.Black,
Alpha = 0.4f,
Icon = FontAwesome.Solid.CircleNotch
},
spinner = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Icon = FontAwesome.Solid.CircleNotch
}
};
}
@ -34,12 +53,11 @@ namespace osu.Game.Graphics.UserInterface
{
base.LoadComplete();
spinner.Spin(2000, RotationDirection.Clockwise);
spinner.Spin(spin_duration, RotationDirection.Clockwise);
spinnerShadow.Spin(spin_duration, RotationDirection.Clockwise);
}
private const float transition_duration = 500;
protected override void PopIn() => this.FadeIn(transition_duration * 5, Easing.OutQuint);
protected override void PopIn() => this.FadeIn(transition_duration * 2, Easing.OutQuint);
protected override void PopOut() => this.FadeOut(transition_duration, Easing.OutQuint);
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
namespace osu.Game.Graphics.UserInterface
{

View File

@ -1,12 +1,14 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using OpenTK.Graphics;
using System;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
@ -40,9 +42,9 @@ namespace osu.Game.Graphics.UserInterface
},
};
Current.ValueChanged += newValue =>
Current.ValueChanged += filled =>
{
if (newValue)
if (filled.NewValue)
fill.FadeIn(200, Easing.OutQuint);
else
fill.FadeTo(0.01f, 200, Easing.OutQuint); //todo: remove once we figure why containers aren't drawing at all times
@ -71,9 +73,10 @@ namespace osu.Game.Graphics.UserInterface
}
private bool glowing;
public bool Glowing
{
get { return glowing; }
get => glowing;
set
{
glowing = value;
@ -93,18 +96,29 @@ namespace osu.Game.Graphics.UserInterface
public bool Expanded
{
set => this.ResizeTo(new Vector2(value ? EXPANDED_SIZE : COLLAPSED_SIZE, 12), 500, Easing.OutQuint);
}
private readonly Bindable<bool> current = new Bindable<bool>();
public Bindable<bool> Current
{
get => current;
set
{
this.ResizeTo(new Vector2(value ? EXPANDED_SIZE : COLLAPSED_SIZE, 12), 500, Easing.OutQuint);
if (value == null)
throw new ArgumentNullException(nameof(value));
current.UnbindBindings();
current.BindTo(value);
}
}
public Bindable<bool> Current { get; } = new Bindable<bool>();
private Color4 accentColour;
public Color4 AccentColour
{
get { return accentColour; }
get => accentColour;
set
{
accentColour = value;
@ -114,9 +128,10 @@ namespace osu.Game.Graphics.UserInterface
}
private Color4 glowingAccentColour;
public Color4 GlowingAccentColour
{
get { return glowingAccentColour; }
get => glowingAccentColour;
set
{
glowingAccentColour = value;
@ -126,9 +141,10 @@ namespace osu.Game.Graphics.UserInterface
}
private Color4 glowColour;
public Color4 GlowColour
{
get { return glowColour; }
get => glowColour;
set
{
glowColour = value;

View File

@ -0,0 +1,110 @@
// 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.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
/// <summary>
/// Highlight on hover, bounce on click.
/// </summary>
public class OsuAnimatedButton : OsuClickableContainer
{
/// <summary>
/// The colour that should be flashed when the <see cref="IconButton"/> is clicked.
/// </summary>
protected Color4 FlashColour = Color4.White.Opacity(0.3f);
private Color4 hoverColour = Color4.White.Opacity(0.1f);
/// <summary>
/// The background colour of the <see cref="IconButton"/> while it is hovered.
/// </summary>
protected Color4 HoverColour
{
get => hoverColour;
set
{
hoverColour = value;
hover.Colour = value;
}
}
protected override Container<Drawable> Content => content;
private readonly Container content;
private readonly Box hover;
public OsuAnimatedButton()
{
base.Content.Add(content = new Container
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
CornerRadius = 5,
Masking = true,
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0.04f),
Type = EdgeEffectType.Shadow,
Radius = 5,
},
Children = new Drawable[]
{
hover = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = HoverColour,
Blending = BlendingMode.Additive,
Alpha = 0,
},
}
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Enabled.BindValueChanged(enabled => this.FadeColour(enabled.NewValue ? Color4.White : colours.Gray9, 200, Easing.OutQuint), true);
}
protected override bool OnHover(HoverEvent e)
{
hover.FadeIn(500, Easing.OutQuint);
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
hover.FadeOut(500, Easing.OutQuint);
base.OnHoverLost(e);
}
protected override bool OnClick(ClickEvent e)
{
hover.FlashColour(FlashColour, 800, Easing.OutQuint);
return base.OnClick(e);
}
protected override bool OnMouseDown(MouseDownEvent e)
{
Content.ScaleTo(0.75f, 2000, Easing.OutQuint);
return base.OnMouseDown(e);
}
protected override bool OnMouseUp(MouseUpEvent e)
{
Content.ScaleTo(1, 1000, Easing.OutElastic);
return base.OnMouseUp(e);
}
}
}

View File

@ -1,7 +1,16 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Sprites;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
@ -10,9 +19,73 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public class OsuButton : Button
{
private Box hover;
public OsuButton()
{
Add(new HoverClickSounds(HoverSampleSet.Loud));
Height = 40;
Content.Masking = true;
Content.CornerRadius = 5;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = colours.BlueDark;
AddRange(new Drawable[]
{
hover = new Box
{
RelativeSizeAxes = Axes.Both,
Blending = BlendingMode.Additive,
Colour = Color4.White.Opacity(0.1f),
Alpha = 0,
Depth = -1
},
new HoverClickSounds(HoverSampleSet.Loud),
});
Enabled.ValueChanged += enabledChanged;
Enabled.TriggerChange();
}
private void enabledChanged(ValueChangedEvent<bool> e)
{
this.FadeColour(e.NewValue ? Color4.White : Color4.Gray, 200, Easing.OutQuint);
}
protected override bool OnHover(HoverEvent e)
{
hover.FadeIn(200);
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
hover.FadeOut(200);
base.OnHoverLost(e);
}
protected override bool OnMouseDown(MouseDownEvent e)
{
Content.ScaleTo(0.9f, 4000, Easing.OutQuint);
return base.OnMouseDown(e);
}
protected override bool OnMouseUp(MouseUpEvent e)
{
Content.ScaleTo(1, 1000, Easing.OutElastic);
return base.OnMouseUp(e);
}
protected override SpriteText CreateText() => new OsuSpriteText
{
Depth = -1,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Font = OsuFont.GetFont(weight: FontWeight.Bold)
};
}
}

View File

@ -1,16 +1,16 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Sprites;
using OpenTK.Graphics;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
@ -33,7 +33,7 @@ namespace osu.Game.Graphics.UserInterface
public string LabelText
{
get { return labelSpriteText?.Text; }
get => labelSpriteText?.Text;
set
{
if (labelSpriteText != null)
@ -43,7 +43,7 @@ namespace osu.Game.Graphics.UserInterface
public MarginPadding LabelPadding
{
get { return labelSpriteText?.Padding ?? new MarginPadding(); }
get => labelSpriteText?.Padding ?? new MarginPadding();
set
{
if (labelSpriteText != null)
@ -86,27 +86,27 @@ namespace osu.Game.Graphics.UserInterface
{
base.LoadComplete();
Current.ValueChanged += newValue =>
Current.ValueChanged += enabled =>
{
if (newValue)
if (enabled.NewValue)
sampleChecked?.Play();
else
sampleUnchecked?.Play();
};
}
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
Nub.Glowing = true;
Nub.Expanded = true;
return base.OnHover(state);
return base.OnHover(e);
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
Nub.Glowing = false;
Nub.Expanded = false;
base.OnHoverLost(state);
base.OnHoverLost(e);
}
[BackgroundDependencyLoader]

View File

@ -1,11 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK.Graphics;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
namespace osu.Game.Graphics.UserInterface
{

View File

@ -1,8 +1,8 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System.Linq;
using OpenTK.Graphics;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@ -10,16 +10,17 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.Sprites;
using OpenTK;
using osuTK;
namespace osu.Game.Graphics.UserInterface
{
public class OsuDropdown<T> : Dropdown<T>, IHasAccentColour
{
private Color4 accentColour;
public Color4 AccentColour
{
get { return accentColour; }
get => accentColour;
set
{
accentColour = value;
@ -30,18 +31,16 @@ namespace osu.Game.Graphics.UserInterface
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == default(Color4))
if (accentColour == default)
accentColour = colours.PinkDarker;
updateAccentColour();
}
private void updateAccentColour()
{
var header = Header as IHasAccentColour;
if (header != null) header.AccentColour = accentColour;
if (Header is IHasAccentColour header) header.AccentColour = accentColour;
var menu = Menu as IHasAccentColour;
if (menu != null) menu.AccentColour = accentColour;
if (Menu is IHasAccentColour menu) menu.AccentColour = accentColour;
}
protected override DropdownHeader CreateHeader() => new OsuDropdownHeader();
@ -49,8 +48,11 @@ namespace osu.Game.Graphics.UserInterface
protected override DropdownMenu CreateMenu() => new OsuDropdownMenu();
#region OsuDropdownMenu
protected class OsuDropdownMenu : DropdownMenu, IHasAccentColour
{
public override bool HandleNonPositionalInput => State == MenuState.Open;
// todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring
public OsuDropdownMenu()
{
@ -81,9 +83,10 @@ namespace osu.Game.Graphics.UserInterface
}
private Color4 accentColour;
public Color4 AccentColour
{
get { return accentColour; }
get => accentColour;
set
{
accentColour = value;
@ -95,12 +98,17 @@ namespace osu.Game.Graphics.UserInterface
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour };
#region DrawableOsuDropdownMenuItem
public class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour
{
// IsHovered is used
public override bool HandlePositionalInput => true;
private Color4? accentColour;
public Color4 AccentColour
{
get { return accentColour ?? nonAccentSelectedColour; }
get => accentColour ?? nonAccentSelectedColour;
set
{
accentColour = value;
@ -144,8 +152,7 @@ namespace osu.Game.Graphics.UserInterface
{
base.UpdateForegroundColour();
var content = Foreground.Children.FirstOrDefault() as Content;
if (content != null) content.Chevron.Alpha = IsHovered ? 1 : 0;
if (Foreground.Children.FirstOrDefault() is Content content) content.Chevron.Alpha = IsHovered ? 1 : 0;
}
protected override Drawable CreateContent() => new Content();
@ -154,8 +161,8 @@ namespace osu.Game.Graphics.UserInterface
{
public string Text
{
get { return Label.Text; }
set { Label.Text = value; }
get => Label.Text;
set => Label.Text = value;
}
public readonly OsuSpriteText Label;
@ -172,7 +179,7 @@ namespace osu.Game.Graphics.UserInterface
Chevron = new SpriteIcon
{
AlwaysPresent = true,
Icon = FontAwesome.fa_chevron_right,
Icon = FontAwesome.Solid.ChevronRight,
Colour = Color4.Black,
Alpha = 0.5f,
Size = new Vector2(8),
@ -189,25 +196,29 @@ namespace osu.Game.Graphics.UserInterface
}
}
}
#endregion
}
#endregion
public class OsuDropdownHeader : DropdownHeader, IHasAccentColour
{
protected readonly SpriteText Text;
protected override string Label
{
get { return Text.Text; }
set { Text.Text = value; }
get => Text.Text;
set => Text.Text = value;
}
protected readonly SpriteIcon Icon;
private Color4 accentColour;
public virtual Color4 AccentColour
{
get { return accentColour; }
get => accentColour;
set
{
accentColour = value;
@ -233,7 +244,7 @@ namespace osu.Game.Graphics.UserInterface
},
Icon = new SpriteIcon
{
Icon = FontAwesome.fa_chevron_down,
Icon = FontAwesome.Solid.ChevronDown,
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Margin = new MarginPadding { Right = 4 },

View File

@ -1,10 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using System.ComponentModel;
using System.Reflection;
using System.Collections.Generic;
namespace osu.Game.Graphics.UserInterface
{
@ -15,18 +12,7 @@ namespace osu.Game.Graphics.UserInterface
if (!typeof(T).IsEnum)
throw new InvalidOperationException("OsuEnumDropdown only supports enums as the generic type argument");
List<KeyValuePair<string, T>> items = new List<KeyValuePair<string, T>>();
foreach (var val in (T[])Enum.GetValues(typeof(T)))
{
var field = typeof(T).GetField(Enum.GetName(typeof(T), val));
items.Add(
new KeyValuePair<string, T>(
field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? Enum.GetName(typeof(T), val),
val
)
);
}
Items = items;
Items = (T[])Enum.GetValues(typeof(T));
}
}
}

View File

@ -1,18 +1,18 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using OpenTK.Graphics;
using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Sprites;
using OpenTK;
using osuTK;
namespace osu.Game.Graphics.UserInterface
{
@ -88,34 +88,36 @@ namespace osu.Game.Graphics.UserInterface
case MenuItemType.Standard:
text.Colour = Color4.White;
break;
case MenuItemType.Destructive:
text.Colour = Color4.Red;
break;
case MenuItemType.Highlighted:
text.Colour = OsuColour.FromHex(@"ffcc22");
break;
}
}
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
sampleHover.Play();
text.BoldText.FadeIn(transition_length, Easing.OutQuint);
text.NormalText.FadeOut(transition_length, Easing.OutQuint);
return base.OnHover(state);
return base.OnHover(e);
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
text.BoldText.FadeOut(transition_length, Easing.OutQuint);
text.NormalText.FadeIn(transition_length, Easing.OutQuint);
base.OnHoverLost(state);
base.OnHoverLost(e);
}
protected override bool OnClick(InputState state)
protected override bool OnClick(ClickEvent e)
{
sampleClick.Play();
return base.OnClick(state);
return base.OnClick(e);
}
protected sealed override Drawable CreateContent() => text = CreateTextContainer();
@ -125,7 +127,7 @@ namespace osu.Game.Graphics.UserInterface
{
public string Text
{
get { return NormalText.Text; }
get => NormalText.Text;
set
{
NormalText.Text = value;
@ -149,7 +151,7 @@ namespace osu.Game.Graphics.UserInterface
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = text_size,
Font = OsuFont.GetFont(size: text_size),
Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL },
},
BoldText = new OsuSpriteText
@ -158,8 +160,7 @@ namespace osu.Game.Graphics.UserInterface
Alpha = 0,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = text_size,
Font = @"Exo2.0-Bold",
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold),
Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL },
}
};

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using osu.Framework.Graphics.UserInterface;

View File

@ -1,24 +1,26 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
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.Input;
using osu.Framework.Input.Events;
using osu.Framework.Platform;
namespace osu.Game.Graphics.UserInterface
{
public class OsuPasswordTextBox : OsuTextBox
public class OsuPasswordTextBox : OsuTextBox, ISuppressKeyEventLogging
{
protected override Drawable GetDrawableCharacter(char c) => new PasswordMaskChar(CalculatedTextSize);
public override bool AllowClipboardExport => false;
protected override bool AllowClipboardExport => false;
private readonly CapsWarning warning;
@ -42,23 +44,23 @@ namespace osu.Game.Graphics.UserInterface
this.host = host;
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
protected override bool OnKeyDown(KeyDownEvent e)
{
if (args.Key == Key.CapsLock)
if (e.Key == Key.CapsLock)
updateCapsWarning(host.CapsLockEnabled);
return base.OnKeyDown(state, args);
return base.OnKeyDown(e);
}
protected override void OnFocus(InputState state)
protected override void OnFocus(FocusEvent e)
{
updateCapsWarning(host.CapsLockEnabled);
base.OnFocus(state);
base.OnFocus(e);
}
protected override void OnFocusLost(InputState state)
protected override void OnFocusLost(FocusLostEvent e)
{
updateCapsWarning(false);
base.OnFocusLost(state);
base.OnFocusLost(e);
}
private void updateCapsWarning(bool visible) => warning.FadeTo(visible ? 1 : 0, 250, Easing.OutQuint);
@ -106,7 +108,7 @@ namespace osu.Game.Graphics.UserInterface
public CapsWarning()
{
Icon = FontAwesome.fa_warning;
Icon = FontAwesome.Solid.ExclamationTriangle;
}
[BackgroundDependencyLoader]

View File

@ -1,19 +1,18 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using System.Globalization;
using OpenTK;
using OpenTK.Graphics;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
{
@ -33,43 +32,13 @@ namespace osu.Game.Graphics.UserInterface
private readonly Box leftBox;
private readonly Box rightBox;
public virtual string TooltipText
{
get
{
var bindableDouble = CurrentNumber as BindableNumber<double>;
var bindableFloat = CurrentNumber as BindableNumber<float>;
var floatValue = bindableDouble?.Value ?? bindableFloat?.Value;
var floatPrecision = bindableDouble?.Precision ?? bindableFloat?.Precision;
if (floatValue != null)
{
var floatMinValue = bindableDouble?.MinValue ?? bindableFloat.MinValue;
var floatMaxValue = bindableDouble?.MaxValue ?? bindableFloat.MaxValue;
if (floatMaxValue == 1 && (floatMinValue == 0 || floatMinValue == -1))
return floatValue.Value.ToString("P0");
var decimalPrecision = normalise((decimal)floatPrecision, max_decimal_digits);
// Find the number of significant digits (we could have less than 5 after normalize())
var significantDigits = findPrecision(decimalPrecision);
return floatValue.Value.ToString($"N{significantDigits}");
}
var bindableInt = CurrentNumber as BindableNumber<int>;
if (bindableInt != null)
return bindableInt.Value.ToString("N0");
return Current.Value.ToString(CultureInfo.InvariantCulture);
}
}
public virtual string TooltipText { get; private set; }
private Color4 accentColour;
public Color4 AccentColour
{
get { return accentColour; }
get => accentColour;
set
{
accentColour = value;
@ -111,10 +80,7 @@ namespace osu.Game.Graphics.UserInterface
new HoverClickSounds()
};
Current.DisabledChanged += disabled =>
{
Alpha = disabled ? 0.3f : 1;
};
Current.DisabledChanged += disabled => { Alpha = disabled ? 0.3f : 1; };
}
[BackgroundDependencyLoader]
@ -124,33 +90,52 @@ namespace osu.Game.Graphics.UserInterface
AccentColour = colours.Pink;
}
protected override bool OnHover(InputState state)
protected override void LoadComplete()
{
base.LoadComplete();
CurrentNumber.BindValueChanged(current => updateTooltipText(current.NewValue), true);
}
protected override bool OnHover(HoverEvent e)
{
Nub.Glowing = true;
return base.OnHover(state);
return base.OnHover(e);
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
Nub.Glowing = false;
base.OnHoverLost(state);
base.OnHoverLost(e);
}
protected override void OnUserChange()
protected override bool OnMouseDown(MouseDownEvent e)
{
base.OnUserChange();
playSample();
Nub.Current.Value = true;
return base.OnMouseDown(e);
}
private void playSample()
protected override bool OnMouseUp(MouseUpEvent e)
{
Nub.Current.Value = false;
return base.OnMouseUp(e);
}
protected override void OnUserChange(T value)
{
base.OnUserChange(value);
playSample(value);
updateTooltipText(value);
}
private void playSample(T value)
{
if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50)
return;
if (Current.Value.Equals(lastSampleValue))
if (value.Equals(lastSampleValue))
return;
lastSampleValue = Current.Value;
lastSampleValue = value;
lastSampleTime = Clock.CurrentTime;
sample.Frequency.Value = 1 + NormalizedValue * 0.2f;
@ -163,16 +148,28 @@ namespace osu.Game.Graphics.UserInterface
sample.Play();
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
private void updateTooltipText(T value)
{
Nub.Current.Value = true;
return base.OnMouseDown(state, args);
}
if (CurrentNumber.IsInteger)
TooltipText = ((int)Convert.ChangeType(value, typeof(int))).ToString("N0");
else
{
double floatValue = (double)Convert.ChangeType(value, typeof(double));
double floatMinValue = (double)Convert.ChangeType(CurrentNumber.MinValue, typeof(double));
double floatMaxValue = (double)Convert.ChangeType(CurrentNumber.MaxValue, typeof(double));
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
Nub.Current.Value = false;
return base.OnMouseUp(state, args);
if (floatMaxValue == 1 && floatMinValue >= -1)
TooltipText = floatValue.ToString("P0");
else
{
var decimalPrecision = normalise((decimal)Convert.ChangeType(CurrentNumber.Precision, typeof(decimal)), max_decimal_digits);
// Find the number of significant digits (we could have less than 5 after normalize())
var significantDigits = findPrecision(decimalPrecision);
TooltipText = floatValue.ToString($"N{significantDigits}");
}
}
}
protected override void UpdateAfterChildren()
@ -206,6 +203,7 @@ namespace osu.Game.Graphics.UserInterface
private int findPrecision(decimal d)
{
int precision = 0;
while (d != Math.Round(d))
{
d *= 10;

View File

@ -1,12 +1,12 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using System.Linq;
using OpenTK;
using OpenTK.Graphics;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@ -14,7 +14,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Framework.MathUtils;
using osu.Game.Graphics.Sprites;
@ -37,7 +37,7 @@ namespace osu.Game.Graphics.UserInterface
{
TabContainer.Spacing = new Vector2(10f, 0f);
Add(strip = new Box
AddInternal(strip = new Box
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
@ -53,19 +53,19 @@ namespace osu.Game.Graphics.UserInterface
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == default(Color4))
if (accentColour == default)
AccentColour = colours.Blue;
}
private Color4 accentColour;
public Color4 AccentColour
{
get { return accentColour; }
get => accentColour;
set
{
accentColour = value;
var dropdown = Dropdown as IHasAccentColour;
if (dropdown != null)
if (Dropdown is IHasAccentColour dropdown)
dropdown.AccentColour = value;
foreach (var i in TabContainer.Children.OfType<IHasAccentColour>())
i.AccentColour = value;
@ -101,13 +101,14 @@ namespace osu.Game.Graphics.UserInterface
protected readonly Box Bar;
private Color4 accentColour;
public Color4 AccentColour
{
get { return accentColour; }
get => accentColour;
set
{
accentColour = value;
if (!Active)
if (!Active.Value)
Text.Colour = value;
}
}
@ -126,27 +127,28 @@ namespace osu.Game.Graphics.UserInterface
Text.FadeColour(AccentColour, transition_length, Easing.OutQuint);
}
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
if (!Active)
if (!Active.Value)
fadeActive();
return true;
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
if (!Active)
if (!Active.Value)
fadeInactive();
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == default(Color4))
if (accentColour == default)
AccentColour = colours.Blue;
}
public OsuTabItem(T value) : base(value)
public OsuTabItem(T value)
: base(value)
{
AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y;
@ -159,8 +161,7 @@ namespace osu.Game.Graphics.UserInterface
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Text = (value as IHasDescription)?.Description ?? (value as Enum)?.GetDescription() ?? value.ToString(),
TextSize = 14,
Font = @"Exo2.0-Bold", // Font should only turn bold when active?
Font = OsuFont.GetFont(size: 14)
},
Bar = new Box
{
@ -173,6 +174,8 @@ namespace osu.Game.Graphics.UserInterface
},
new HoverClickSounds()
};
Active.BindValueChanged(active => Text.Font = Text.Font.With(Typeface.Exo, weight: active.NewValue ? FontWeight.Bold : FontWeight.Medium), true);
}
protected override void OnActivated() => fadeActive();
@ -223,11 +226,7 @@ namespace osu.Game.Graphics.UserInterface
{
public override Color4 AccentColour
{
get
{
return base.AccentColour;
}
get => base.AccentColour;
set
{
base.AccentColour = value;
@ -255,7 +254,7 @@ namespace osu.Game.Graphics.UserInterface
{
new SpriteIcon
{
Icon = FontAwesome.fa_ellipsis_h,
Icon = FontAwesome.Solid.EllipsisH,
Size = new Vector2(14),
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
@ -265,16 +264,16 @@ namespace osu.Game.Graphics.UserInterface
Padding = new MarginPadding { Left = 5, Right = 5 };
}
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
Foreground.Colour = BackgroundColour;
return base.OnHover(state);
return base.OnHover(e);
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
Foreground.Colour = BackgroundColourHover;
base.OnHoverLost(state);
base.OnHoverLost(e);
}
}
}

View File

@ -1,8 +1,8 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using OpenTK.Graphics;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -10,7 +10,7 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Sprites;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
{
@ -24,14 +24,15 @@ namespace osu.Game.Graphics.UserInterface
private readonly SpriteIcon icon;
private Color4? accentColour;
public Color4 AccentColour
{
get { return accentColour.GetValueOrDefault(); }
get => accentColour.GetValueOrDefault();
set
{
accentColour = value;
if (Current)
if (Current.Value)
{
text.Colour = AccentColour;
icon.Colour = AccentColour;
@ -41,8 +42,8 @@ namespace osu.Game.Graphics.UserInterface
public string Text
{
get { return text.Text; }
set { text.Text = value; }
get => text.Text;
set => text.Text = value;
}
private const float transition_length = 500;
@ -59,18 +60,18 @@ namespace osu.Game.Graphics.UserInterface
text.FadeColour(AccentColour, transition_length, Easing.OutQuint);
}
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
fadeIn();
return base.OnHover(state);
return base.OnHover(e);
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
if (!Current)
if (!Current.Value)
fadeOut();
base.OnHoverLost(state);
base.OnHoverLost(e);
}
[BackgroundDependencyLoader]
@ -94,15 +95,11 @@ namespace osu.Game.Graphics.UserInterface
Direction = FillDirection.Horizontal,
Children = new Drawable[]
{
text = new OsuSpriteText
{
TextSize = 14,
Font = @"Exo2.0-Bold",
},
text = new OsuSpriteText { Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold) },
icon = new SpriteIcon
{
Size = new Vector2(14),
Icon = FontAwesome.fa_circle_o,
Icon = FontAwesome.Regular.Circle,
Shadow = true,
},
},
@ -118,17 +115,17 @@ namespace osu.Game.Graphics.UserInterface
}
};
Current.ValueChanged += v =>
Current.ValueChanged += selected =>
{
if (v)
if (selected.NewValue)
{
fadeIn();
icon.Icon = FontAwesome.fa_check_circle_o;
icon.Icon = FontAwesome.Regular.CheckCircle;
}
else
{
fadeOut();
icon.Icon = FontAwesome.fa_circle_o;
icon.Icon = FontAwesome.Regular.Circle;
}
};
}

View File

@ -1,28 +1,26 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Graphics.Sprites;
using OpenTK.Graphics;
using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Input.Bindings;
namespace osu.Game.Graphics.UserInterface
{
public class OsuTextBox : TextBox
public class OsuTextBox : TextBox, IKeyBindingHandler<GlobalAction>
{
protected override Color4 BackgroundUnfocused => Color4.Black.Opacity(0.5f);
protected override Color4 BackgroundFocused => OsuColour.Gray(0.3f).Opacity(0.8f);
protected override Color4 BackgroundCommit => BorderColour;
protected override float LeftRightPadding => 10;
protected override SpriteText CreatePlaceholder() => new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
Font = OsuFont.GetFont(italics: true),
Colour = new Color4(180, 180, 180, 255),
Margin = new MarginPadding { Left = 2 },
};
@ -34,31 +32,43 @@ namespace osu.Game.Graphics.UserInterface
CornerRadius = 5;
LengthLimit = 1000;
Current.DisabledChanged += disabled =>
{
Alpha = disabled ? 0.3f : 1;
};
Current.DisabledChanged += disabled => { Alpha = disabled ? 0.3f : 1; };
}
[BackgroundDependencyLoader]
private void load(OsuColour colour)
{
BorderColour = colour.Yellow;
BackgroundUnfocused = Color4.Black.Opacity(0.5f);
BackgroundFocused = OsuColour.Gray(0.3f).Opacity(0.8f);
BackgroundCommit = BorderColour = colour.Yellow;
}
protected override void OnFocus(InputState state)
protected override void OnFocus(FocusEvent e)
{
BorderThickness = 3;
base.OnFocus(state);
base.OnFocus(e);
}
protected override void OnFocusLost(InputState state)
protected override void OnFocusLost(FocusLostEvent e)
{
BorderThickness = 0;
base.OnFocusLost(state);
base.OnFocusLost(e);
}
protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), TextSize = CalculatedTextSize };
protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) };
public virtual bool OnPressed(GlobalAction action)
{
if (action == GlobalAction.Back)
{
KillFocus();
return true;
}
return false;
}
public bool OnReleased(GlobalAction action) => false;
}
}

View File

@ -1,16 +1,16 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using OpenTK;
using OpenTK.Graphics;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface
@ -32,7 +32,8 @@ namespace osu.Game.Graphics.UserInterface
protected readonly SpriteText Text;
public PageTabItem(T value) : base(value)
public PageTabItem(T value)
: base(value)
{
AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y;
@ -45,8 +46,7 @@ namespace osu.Game.Graphics.UserInterface
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Text = (value as Enum)?.GetDescription() ?? value.ToString(),
TextSize = 14,
Font = @"Exo2.0-Bold",
Font = OsuFont.GetFont(size: 14)
},
box = new Box
{
@ -59,6 +59,8 @@ namespace osu.Game.Graphics.UserInterface
},
new HoverClickSounds()
};
Active.BindValueChanged(active => Text.Font = Text.Font.With(Typeface.Exo, weight: active.NewValue ? FontWeight.Bold : FontWeight.Medium), true);
}
[BackgroundDependencyLoader]
@ -67,16 +69,16 @@ namespace osu.Game.Graphics.UserInterface
box.Colour = colours.Yellow;
}
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
if (!Active)
if (!Active.Value)
slideActive();
return true;
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
if (!Active)
if (!Active.Value)
slideInactive();
}

View File

@ -1,7 +1,8 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using osu.Framework.Allocation;
namespace osu.Game.Graphics.UserInterface
{
@ -21,10 +22,13 @@ namespace osu.Game.Graphics.UserInterface
public PercentageCounter()
{
DisplayedCountSpriteText.FixedWidth = true;
DisplayedCountSpriteText.Font = DisplayedCountSpriteText.Font.With(fixedWidth: true);
Current.Value = DisplayedCount = 1.0f;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours) => AccentColour = colours.BlueLighter;
protected override string FormatCount(double count)
{
return $@"{count:P2}";
@ -37,7 +41,7 @@ namespace osu.Game.Graphics.UserInterface
public override void Increment(double amount)
{
Current.Value = Current + amount;
Current.Value = Current.Value + amount;
}
}
}

View File

@ -0,0 +1,56 @@
// 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.Shapes;
using osu.Framework.Input.Events;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
/// <summary>
/// An overlay that will consume all available space and block input when required.
/// Useful for disabling all elements in a form and showing we are waiting on a response, for instance.
/// </summary>
public class ProcessingOverlay : VisibilityContainer
{
private const float transition_duration = 200;
public ProcessingOverlay()
{
RelativeSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load()
{
InternalChildren = new Drawable[]
{
new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
Alpha = 0.9f,
},
new LoadingAnimation { State = Visibility.Visible }
};
}
protected override bool Handle(UIEvent e)
{
return true;
}
protected override void PopIn()
{
this.FadeIn(transition_duration * 2, Easing.OutQuint);
}
protected override void PopOut()
{
this.FadeOut(transition_duration, Easing.OutQuint);
}
}
}

View File

@ -1,11 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using OpenTK.Graphics;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface
public Color4 FillColour
{
set { fill.FadeColour(value, 150, Easing.OutQuint); }
set => fill.FadeColour(value, 150, Easing.OutQuint);
}
public Color4 BackgroundColour
@ -32,12 +32,12 @@ namespace osu.Game.Graphics.UserInterface
public double EndTime
{
set { CurrentNumber.MaxValue = value; }
set => CurrentNumber.MaxValue = value;
}
public double CurrentTime
{
set { CurrentNumber.Value = value; }
set => CurrentNumber.Value = value;
}
public ProgressBar()
@ -62,6 +62,6 @@ namespace osu.Game.Graphics.UserInterface
fill.Width = value * UsableWidth;
}
protected override void OnUserChange() => OnSeek?.Invoke(Current);
protected override void OnUserChange(double value) => OnSeek?.Invoke(value);
}
}

View File

@ -1,14 +1,14 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Sprites;
using System;
using System.Collections.Generic;
using OpenTK.Graphics;
using osu.Framework.Bindables;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
@ -45,15 +45,13 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public virtual T DisplayedCount
{
get
{
return displayedCount;
}
get => displayedCount;
set
{
if (EqualityComparer<T>.Default.Equals(displayedCount, value))
return;
displayedCount = value;
DisplayedCountSpriteText.Text = FormatCount(value);
}
@ -61,22 +59,16 @@ namespace osu.Game.Graphics.UserInterface
public abstract void Increment(T amount);
private float textSize;
public float TextSize
{
get { return textSize; }
set
{
textSize = value;
DisplayedCountSpriteText.TextSize = value;
}
get => DisplayedCountSpriteText.Font.Size;
set => DisplayedCountSpriteText.Font = DisplayedCountSpriteText.Font.With(size: value);
}
public Color4 AccentColour
{
get { return DisplayedCountSpriteText.Colour; }
set { DisplayedCountSpriteText.Colour = value; }
get => DisplayedCountSpriteText.Colour;
set => DisplayedCountSpriteText.Colour = value;
}
/// <summary>
@ -86,20 +78,17 @@ namespace osu.Game.Graphics.UserInterface
{
Children = new Drawable[]
{
DisplayedCountSpriteText = new OsuSpriteText
{
Font = @"Venera"
},
DisplayedCountSpriteText = new OsuSpriteText { Font = OsuFont.Numeric }
};
TextSize = 40;
AutoSizeAxes = Axes.Both;
DisplayedCount = Current;
DisplayedCount = Current.Value;
Current.ValueChanged += newValue =>
Current.ValueChanged += val =>
{
if (IsLoaded) TransformCount(displayedCount, newValue);
if (IsLoaded) TransformCount(displayedCount, val.NewValue);
};
}
@ -107,7 +96,7 @@ namespace osu.Game.Graphics.UserInterface
{
base.LoadComplete();
DisplayedCountSpriteText.Text = FormatCount(Current);
DisplayedCountSpriteText.Text = FormatCount(Current.Value);
}
/// <summary>
@ -126,7 +115,7 @@ namespace osu.Game.Graphics.UserInterface
public virtual void StopRolling()
{
FinishTransforms(false, nameof(DisplayedCount));
DisplayedCount = Current;
DisplayedCount = Current.Value;
}
/// <summary>
@ -134,7 +123,7 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public virtual void ResetCount()
{
SetCountWithoutRolling(default(T));
SetCountWithoutRolling(default);
}
/// <summary>

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
namespace osu.Game.Graphics.UserInterface
@ -27,10 +28,13 @@ namespace osu.Game.Graphics.UserInterface
/// <param name="leading">How many leading zeroes the counter will have.</param>
public ScoreCounter(uint leading = 0)
{
DisplayedCountSpriteText.FixedWidth = true;
DisplayedCountSpriteText.Font = DisplayedCountSpriteText.Font.With(fixedWidth: true);
LeadingZeroes = leading;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours) => AccentColour = colours.BlueLighter;
protected override double GetProportionalDuration(double currentValue, double newValue)
{
return currentValue > newValue ? currentValue - newValue : newValue - currentValue;
@ -48,7 +52,7 @@ namespace osu.Game.Graphics.UserInterface
public override void Increment(double amount)
{
Current.Value = Current + amount;
Current.Value = Current.Value + amount;
}
}
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
@ -8,47 +8,32 @@ using osu.Framework.Screens;
namespace osu.Game.Graphics.UserInterface
{
/// <summary>
/// A <see cref="BreadcrumbControl"/> which follows the active screen (and allows navigation) in a <see cref="Screen"/> stack.
/// A <see cref="BreadcrumbControl{IScreen}"/> which follows the active screen (and allows navigation) in a <see cref="Screen"/> stack.
/// </summary>
public class ScreenBreadcrumbControl : BreadcrumbControl<Screen>
public class ScreenBreadcrumbControl : BreadcrumbControl<IScreen>
{
private Screen last;
public ScreenBreadcrumbControl(Screen initialScreen)
public ScreenBreadcrumbControl(ScreenStack stack)
{
Current.ValueChanged += newScreen =>
{
if (last != newScreen && !newScreen.IsCurrentScreen)
newScreen.MakeCurrent();
};
stack.ScreenPushed += onPushed;
stack.ScreenExited += onExited;
onPushed(initialScreen);
onPushed(null, stack.CurrentScreen);
Current.ValueChanged += current => current.NewValue.MakeCurrent();
}
private void screenChanged(Screen newScreen)
private void onPushed(IScreen lastScreen, IScreen newScreen)
{
if (newScreen == null) return;
if (last != null)
{
last.Exited -= screenChanged;
last.ModePushed -= onPushed;
}
last = newScreen;
newScreen.Exited += screenChanged;
newScreen.ModePushed += onPushed;
AddItem(newScreen);
Current.Value = newScreen;
}
private void onPushed(Screen screen)
private void onExited(IScreen lastScreen, IScreen newScreen)
{
Items.ToList().SkipWhile(i => i != Current.Value).Skip(1).ForEach(RemoveItem);
AddItem(screen);
if (newScreen != null)
Current.Value = newScreen;
screenChanged(screen);
Items.ToList().SkipWhile(s => s != Current.Value).Skip(1).ForEach(RemoveItem);
}
}
}

View File

@ -0,0 +1,82 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Sprites;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
public abstract class ScreenTitle : CompositeDrawable, IHasAccentColour
{
private readonly SpriteIcon iconSprite;
private readonly OsuSpriteText titleText, pageText;
public const float ICON_WIDTH = icon_size + icon_spacing;
private const float icon_size = 25, icon_spacing = 10;
protected IconUsage Icon
{
get => iconSprite.Icon;
set => iconSprite.Icon = value;
}
protected string Title
{
get => titleText.Text;
set => titleText.Text = value;
}
protected string Section
{
get => pageText.Text;
set => pageText.Text = value;
}
public Color4 AccentColour
{
get => pageText.Colour;
set => pageText.Colour = value;
}
protected ScreenTitle()
{
AutoSizeAxes = Axes.Both;
InternalChildren = new Drawable[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Spacing = new Vector2(icon_spacing, 0),
Children = new Drawable[]
{
iconSprite = new SpriteIcon
{
Size = new Vector2(icon_size),
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(6, 0),
Children = new[]
{
titleText = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 25),
},
pageText = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 25),
}
}
}
}
},
};
}
}
}

View File

@ -1,10 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics;
using osu.Framework.Input;
using OpenTK;
using OpenTK.Input;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osuTK;
using osuTK.Input;
namespace osu.Game.Graphics.UserInterface
{
@ -21,7 +22,7 @@ namespace osu.Game.Graphics.UserInterface
{
new SpriteIcon
{
Icon = FontAwesome.fa_search,
Icon = FontAwesome.Solid.Search,
Origin = Anchor.CentreRight,
Anchor = Anchor.CentreRight,
Margin = new MarginPadding { Right = 10 },
@ -32,13 +33,11 @@ namespace osu.Game.Graphics.UserInterface
PlaceholderText = "type to search";
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
protected override bool OnKeyDown(KeyDownEvent e)
{
if (HandlePendingText(state)) return true;
if (!state.Keyboard.ControlPressed && !state.Keyboard.ShiftPressed)
if (!e.ControlPressed && !e.ShiftPressed)
{
switch (args.Key)
switch (e.Key)
{
case Key.Left:
case Key.Right:
@ -50,7 +49,7 @@ namespace osu.Game.Graphics.UserInterface
if (!AllowCommit)
{
switch (args.Key)
switch (e.Key)
{
case Key.KeypadEnter:
case Key.Enter:
@ -58,16 +57,16 @@ namespace osu.Game.Graphics.UserInterface
}
}
if (state.Keyboard.ShiftPressed)
if (e.ShiftPressed)
{
switch (args.Key)
switch (e.Key)
{
case Key.Delete:
return false;
}
}
return base.OnKeyDown(state, args);
return base.OnKeyDown(e);
}
}
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
namespace osu.Game.Graphics.UserInterface
{

View File

@ -1,7 +1,8 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System;
using osu.Framework.Allocation;
namespace osu.Game.Graphics.UserInterface
{
@ -17,6 +18,9 @@ namespace osu.Game.Graphics.UserInterface
Current.Value = DisplayedCount = 0;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours) => AccentColour = colours.BlueLighter;
protected override string FormatCount(int count)
{
return $@"{count}x";
@ -29,7 +33,7 @@ namespace osu.Game.Graphics.UserInterface
public override void Increment(int amount)
{
Current.Value = Current + amount;
Current.Value = Current.Value + amount;
}
}
}

View File

@ -1,12 +1,13 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using OpenTK;
using osuTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using System;
using System.Linq;
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface
{
@ -41,10 +42,7 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public float CountStars
{
get
{
return countStars;
}
get => countStars;
set
{
@ -102,6 +100,7 @@ namespace osu.Game.Graphics.UserInterface
public void StopAnimation()
{
int i = 0;
foreach (var star in stars.Children)
{
star.ClearTransforms(true);
@ -122,6 +121,7 @@ namespace osu.Game.Graphics.UserInterface
private void transformCount(float newValue)
{
int i = 0;
foreach (var star in stars.Children)
{
star.ClearTransforms(true);
@ -137,6 +137,7 @@ namespace osu.Game.Graphics.UserInterface
private class Star : Container
{
public readonly SpriteIcon Icon;
public Star()
{
Size = new Vector2(star_size);
@ -144,7 +145,7 @@ namespace osu.Game.Graphics.UserInterface
Child = Icon = new SpriteIcon
{
Size = new Vector2(star_size),
Icon = FontAwesome.fa_star,
Icon = FontAwesome.Solid.Star,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
};

View File

@ -1,17 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using System.Collections.Generic;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface
{
@ -20,89 +14,26 @@ namespace osu.Game.Graphics.UserInterface
/// </summary>
public class TriangleButton : OsuButton, IFilterable
{
private Box hover;
protected Triangles Triangles;
public TriangleButton()
{
Height = 40;
}
protected override SpriteText CreateText() => new OsuSpriteText
{
Depth = -1,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Font = @"Exo2.0-Bold",
};
protected Triangles Triangles { get; private set; }
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = colours.BlueDark;
Content.Masking = true;
Content.CornerRadius = 5;
AddRange(new Drawable[]
Add(Triangles = new Triangles
{
Triangles = new Triangles
{
RelativeSizeAxes = Axes.Both,
ColourDark = colours.BlueDarker,
ColourLight = colours.Blue,
},
hover = new Box
{
RelativeSizeAxes = Axes.Both,
Blending = BlendingMode.Additive,
Colour = Color4.White.Opacity(0.1f),
Alpha = 0,
},
RelativeSizeAxes = Axes.Both,
ColourDark = colours.BlueDarker,
ColourLight = colours.Blue,
});
Enabled.ValueChanged += enabled_ValueChanged;
Enabled.TriggerChange();
}
private void enabled_ValueChanged(bool enabled)
{
this.FadeColour(enabled ? Color4.White : Color4.Gray, 200, Easing.OutQuint);
}
protected override bool OnHover(InputState state)
{
hover.FadeIn(200);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
hover.FadeOut(200);
base.OnHoverLost(state);
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
Content.ScaleTo(0.9f, 4000, Easing.OutQuint);
return base.OnMouseDown(state, args);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
Content.ScaleTo(1, 1000, Easing.OutElastic);
return base.OnMouseUp(state, args);
}
public IEnumerable<string> FilterTerms => new[] { Text };
public virtual IEnumerable<string> FilterTerms => new[] { Text };
public bool MatchingFilter
{
set
{
this.FadeTo(value ? 1 : 0);
}
set => this.FadeTo(value ? 1 : 0);
}
public bool FilteringActive { get; set; }
}
}

View File

@ -1,19 +1,20 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using OpenTK;
using OpenTK.Graphics;
using osuTK;
using osuTK.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Graphics.Containers;
using osu.Game.Beatmaps.ControlPoints;
using osu.Framework.Audio.Track;
using System;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
{
@ -48,23 +49,19 @@ namespace osu.Game.Graphics.UserInterface
public override Anchor Origin
{
get
{
return base.Origin;
}
get => base.Origin;
set
{
base.Origin = value;
c1.Origin = c1.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopLeft : Anchor.TopRight;
c2.Origin = c2.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopRight : Anchor.TopLeft;
c1.Origin = c1.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopLeft : Anchor.TopRight;
c2.Origin = c2.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopRight : Anchor.TopLeft;
X = (value & Anchor.x2) > 0 ? SIZE_RETRACTED.X * shear * 0.5f : 0;
X = value.HasFlag(Anchor.x2) ? SIZE_RETRACTED.X * shear * 0.5f : 0;
Remove(c1);
Remove(c2);
c1.Depth = (value & Anchor.x2) > 0 ? 0 : 1;
c2.Depth = (value & Anchor.x2) > 0 ? 1 : 0;
c1.Depth = value.HasFlag(Anchor.x2) ? 0 : 1;
c2.Depth = value.HasFlag(Anchor.x2) ? 1 : 0;
Add(c1);
Add(c2);
}
@ -153,25 +150,19 @@ namespace osu.Game.Graphics.UserInterface
};
}
public FontAwesome Icon
public IconUsage Icon
{
set
{
bouncingIcon.Icon = value;
}
set => bouncingIcon.Icon = value;
}
public string Text
{
set
{
text.Text = value;
}
set => text.Text = value;
}
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => IconLayer.ReceiveMouseInputAt(screenSpacePos) || TextLayer.ReceiveMouseInputAt(screenSpacePos);
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => IconLayer.ReceivePositionalInputAt(screenSpacePos) || TextLayer.ReceivePositionalInputAt(screenSpacePos);
protected override bool OnHover(InputState state)
protected override bool OnHover(HoverEvent e)
{
this.ResizeTo(SIZE_EXTENDED, transform_time, Easing.OutElastic);
IconLayer.FadeColour(HoverColour, transform_time, Easing.OutElastic);
@ -181,7 +172,7 @@ namespace osu.Game.Graphics.UserInterface
return true;
}
protected override void OnHoverLost(InputState state)
protected override void OnHoverLost(HoverLostEvent e)
{
this.ResizeTo(SIZE_RETRACTED, transform_time, Easing.OutElastic);
IconLayer.FadeColour(TextLayer.Colour, transform_time, Easing.OutElastic);
@ -189,12 +180,12 @@ namespace osu.Game.Graphics.UserInterface
bouncingIcon.ScaleTo(1, transform_time, Easing.OutElastic);
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
protected override bool OnMouseDown(MouseDownEvent e)
{
return true;
}
protected override bool OnClick(InputState state)
protected override bool OnClick(ClickEvent e)
{
var flash = new Box
{
@ -208,7 +199,7 @@ namespace osu.Game.Graphics.UserInterface
flash.FadeOut(500, Easing.OutQuint);
flash.Expire();
return base.OnClick(state);
return base.OnClick(e);
}
private class BouncingIcon : BeatSyncedContainer
@ -217,7 +208,10 @@ namespace osu.Game.Graphics.UserInterface
private readonly SpriteIcon icon;
public FontAwesome Icon { set { icon.Icon = value; } }
public IconUsage Icon
{
set => icon.Icon = value;
}
public BouncingIcon()
{