osukey/osu.Game/Graphics/Cursor/MenuCursor.cs
2017-09-17 01:40:38 +02:00

153 lines
5.5 KiB
C#

// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
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 osu.Framework.Graphics.Textures;
namespace osu.Game.Graphics.Cursor
{
public class MenuCursor : CursorContainer
{
protected override Drawable CreateCursor () => new Cursor();
private Bindable<bool> cursorRotate;
private bool dragging;
private bool startRotation;
protected override bool OnMouseMove (InputState state)
{
if (cursorRotate && dragging) {
Debug.Assert (state.Mouse.PositionMouseDown != null);
// don't start rotating until we're moved a minimum distance away from the mouse down location,
// else it can have an annoying effect.
startRotation |= Vector2Extensions.Distance (state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30;
if (startRotation) {
Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value;
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;
if (diff < -180)
diff += 360;
if (diff > 180)
diff -= 360;
degrees = ActiveCursor.Rotation + diff;
ActiveCursor.RotateTo (degrees, 600, Easing.OutQuint);
}
}
return base.OnMouseMove (state);
}
protected override bool OnDragStart (InputState state)
{
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) {
dragging = false;
startRotation = false;
((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);
}
return base.OnMouseUp (state, args);
}
protected override bool OnClick (InputState state)
{
((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne (500, Easing.OutQuint);
return base.OnClick (state);
}
protected override void PopIn ()
{
ActiveCursor.FadeTo (1, 250, Easing.OutQuint);
ActiveCursor.ScaleTo (1, 400, Easing.OutQuint);
}
protected override void PopOut ()
{
ActiveCursor.FadeTo (0, 900, Easing.OutQuint);
ActiveCursor.ScaleTo (0, 500, Easing.In);
}
[BackgroundDependencyLoader]
private void load (OsuConfigManager config)
{
cursorRotate = config.GetBindable<bool> (OsuSetting.CursorRotation);
}
public class Cursor : Container
{
private Container cursorContainer;
private Bindable<double> cursorScale;
private const float base_scale = 0.15f;
public Sprite AdditiveLayer;
public Cursor ()
{
AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, TextureStore textures, OsuColour colour)
{
Children = new Drawable[] {
cursorContainer = new Container {
AutoSizeAxes = Axes.Both,
Children = new Drawable[] {
new Sprite {
Texture = textures.Get (@"Cursor/menu-cursor"),
},
AdditiveLayer = new Sprite {
Blending = BlendingMode.Additive,
Colour = colour.Pink,
Alpha = 0,
Texture = textures.Get (@"Cursor/menu-cursor-additive"),
},
}
}
};
cursorScale = config.GetBindable<double> (OsuSetting.MenuCursorSize);
cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2 ((float)newScale * base_scale);
cursorScale.TriggerChange();
}
}
}
}