2018-04-13 17:19:50 +08:00
|
|
|
|
// Copyright (c) 2007-2018 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.Game.Configuration;
|
|
|
|
|
using System;
|
2018-04-13 20:13:09 +08:00
|
|
|
|
using JetBrains.Annotations;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
using osu.Framework.Graphics.Textures;
|
2018-07-21 10:38:28 +08:00
|
|
|
|
using osu.Framework.Input.EventArgs;
|
|
|
|
|
using osu.Framework.Input.States;
|
2018-07-02 15:07:52 +08:00
|
|
|
|
using OpenTK.Input;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
|
|
|
|
namespace osu.Game.Graphics.Cursor
|
|
|
|
|
{
|
|
|
|
|
public class MenuCursor : CursorContainer
|
|
|
|
|
{
|
2018-04-13 20:13:09 +08:00
|
|
|
|
private readonly IBindable<bool> screenshotCursorVisibility = new Bindable<bool>(true);
|
|
|
|
|
public override bool IsPresent => screenshotCursorVisibility.Value && base.IsPresent;
|
|
|
|
|
|
2018-07-06 16:45:39 +08:00
|
|
|
|
protected override Drawable CreateCursor() => activeCursor = new Cursor();
|
|
|
|
|
|
|
|
|
|
private Cursor activeCursor;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
|
|
|
|
private Bindable<bool> cursorRotate;
|
2018-07-02 15:07:52 +08:00
|
|
|
|
private DragRotationState dragRotationState;
|
|
|
|
|
private Vector2 positionMouseDown;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
2018-04-13 20:13:09 +08:00
|
|
|
|
[BackgroundDependencyLoader(true)]
|
|
|
|
|
private void load([NotNull] OsuConfigManager config, [CanBeNull] ScreenshotManager screenshotManager)
|
|
|
|
|
{
|
|
|
|
|
cursorRotate = config.GetBindable<bool>(OsuSetting.CursorRotation);
|
|
|
|
|
|
|
|
|
|
if (screenshotManager != null)
|
|
|
|
|
screenshotCursorVisibility.BindTo(screenshotManager.CursorVisibility);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 17:19:50 +08:00
|
|
|
|
protected override bool OnMouseMove(InputState state)
|
|
|
|
|
{
|
2018-07-02 15:07:52 +08:00
|
|
|
|
if (dragRotationState != DragRotationState.NotDragging)
|
2018-04-13 17:19:50 +08:00
|
|
|
|
{
|
2018-07-02 15:07:52 +08:00
|
|
|
|
var position = state.Mouse.Position;
|
|
|
|
|
var distance = Vector2Extensions.Distance(position, positionMouseDown);
|
2018-04-13 17:19:50 +08:00
|
|
|
|
// don't start rotating until we're moved a minimum distance away from the mouse down location,
|
|
|
|
|
// else it can have an annoying effect.
|
2018-07-02 15:07:52 +08:00
|
|
|
|
if (dragRotationState == DragRotationState.DragStarted && distance > 30)
|
|
|
|
|
dragRotationState = DragRotationState.Rotating;
|
2018-07-02 15:09:33 +08:00
|
|
|
|
// don't rotate when distance is zero to avoid NaN
|
2018-07-02 15:07:52 +08:00
|
|
|
|
if (dragRotationState == DragRotationState.Rotating && distance > 0)
|
2018-04-13 17:19:50 +08:00
|
|
|
|
{
|
2018-07-02 15:07:52 +08:00
|
|
|
|
Vector2 offset = state.Mouse.Position - positionMouseDown;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f;
|
|
|
|
|
|
|
|
|
|
// Always rotate in the direction of least distance
|
2018-07-06 16:45:39 +08:00
|
|
|
|
float diff = (degrees - activeCursor.Rotation) % 360;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
if (diff < -180) diff += 360;
|
|
|
|
|
if (diff > 180) diff -= 360;
|
2018-07-06 16:45:39 +08:00
|
|
|
|
degrees = activeCursor.Rotation + diff;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
2018-07-06 16:45:39 +08:00
|
|
|
|
activeCursor.RotateTo(degrees, 600, Easing.OutQuint);
|
2018-04-13 17:19:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return base.OnMouseMove(state);
|
|
|
|
|
}
|
2018-07-02 15:20:44 +08:00
|
|
|
|
|
2018-04-13 17:19:50 +08:00
|
|
|
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
|
|
|
|
{
|
2018-07-02 15:28:05 +08:00
|
|
|
|
// only trigger animation for main mouse buttons
|
|
|
|
|
if (args.Button <= MouseButton.Right)
|
|
|
|
|
{
|
2018-07-06 16:45:39 +08:00
|
|
|
|
activeCursor.Scale = new Vector2(1);
|
|
|
|
|
activeCursor.ScaleTo(0.90f, 800, Easing.OutQuint);
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
2018-07-06 16:45:39 +08:00
|
|
|
|
activeCursor.AdditiveLayer.Alpha = 0;
|
|
|
|
|
activeCursor.AdditiveLayer.FadeInFromZero(800, Easing.OutQuint);
|
2018-07-02 15:28:05 +08:00
|
|
|
|
}
|
2018-07-02 15:07:52 +08:00
|
|
|
|
|
|
|
|
|
if (args.Button == MouseButton.Left && cursorRotate)
|
|
|
|
|
{
|
|
|
|
|
dragRotationState = DragRotationState.DragStarted;
|
|
|
|
|
positionMouseDown = state.Mouse.Position;
|
|
|
|
|
}
|
2018-04-13 17:19:50 +08:00
|
|
|
|
return base.OnMouseDown(state, args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
|
|
|
|
{
|
|
|
|
|
if (!state.Mouse.HasMainButtonPressed)
|
|
|
|
|
{
|
2018-07-06 16:45:39 +08:00
|
|
|
|
activeCursor.AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint);
|
|
|
|
|
activeCursor.ScaleTo(1, 500, Easing.OutElastic);
|
2018-04-13 17:19:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-07-02 15:07:52 +08:00
|
|
|
|
if (args.Button == MouseButton.Left)
|
|
|
|
|
{
|
|
|
|
|
if (dragRotationState == DragRotationState.Rotating)
|
2018-07-06 16:45:39 +08:00
|
|
|
|
activeCursor.RotateTo(0, 600 * (1 + Math.Abs(activeCursor.Rotation / 720)), Easing.OutElasticHalf);
|
2018-07-02 15:07:52 +08:00
|
|
|
|
dragRotationState = DragRotationState.NotDragging;
|
|
|
|
|
}
|
2018-04-13 17:19:50 +08:00
|
|
|
|
return base.OnMouseUp(state, args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void PopIn()
|
|
|
|
|
{
|
2018-07-06 16:45:39 +08:00
|
|
|
|
activeCursor.FadeTo(1, 250, Easing.OutQuint);
|
|
|
|
|
activeCursor.ScaleTo(1, 400, Easing.OutQuint);
|
2018-04-13 17:19:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void PopOut()
|
|
|
|
|
{
|
2018-07-06 16:45:39 +08:00
|
|
|
|
activeCursor.FadeTo(0, 250, Easing.OutQuint);
|
|
|
|
|
activeCursor.ScaleTo(0.6f, 250, Easing.In);
|
2018-04-13 17:19:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-02 15:07:52 +08:00
|
|
|
|
|
|
|
|
|
private enum DragRotationState
|
|
|
|
|
{
|
|
|
|
|
NotDragging,
|
|
|
|
|
DragStarted,
|
|
|
|
|
Rotating,
|
|
|
|
|
}
|
2018-04-13 17:19:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|