Merge branch 'master' of git://github.com/ppy/osu into tooltips

# Conflicts:
#	osu.Game/Graphics/Cursor/MenuCursor.cs
This commit is contained in:
Jorolf
2017-04-13 23:12:07 +02:00
221 changed files with 3921 additions and 2284 deletions

View File

@ -60,8 +60,8 @@ namespace osu.Game.Graphics.Backgrounds
protected override void LoadComplete()
{
base.LoadComplete();
for (int i = 0; i < aimTriangleCount; i++)
addTriangle(true);
addTriangles(true);
}
private int aimTriangleCount => (int)(DrawWidth * DrawHeight * 0.002f / (triangleScale * triangleScale) * SpawnRatio);
@ -83,8 +83,8 @@ namespace osu.Game.Graphics.Backgrounds
t.Expire();
}
while (CreateNewTriangles && Children.Count() < aimTriangleCount)
addTriangle(false);
if (CreateNewTriangles)
addTriangles(false);
}
protected virtual Triangle CreateTriangle()
@ -113,12 +113,16 @@ namespace osu.Game.Graphics.Backgrounds
protected virtual Color4 GetTriangleShade() => Interpolation.ValueAt(RNG.NextSingle(), ColourDark, ColourLight, 0, 1);
private void addTriangle(bool randomY)
private void addTriangles(bool randomY)
{
var sprite = CreateTriangle();
float triangleHeight = sprite.DrawHeight / DrawHeight;
sprite.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() * (1 + triangleHeight) - triangleHeight : 1);
Add(sprite);
int addCount = aimTriangleCount - Children.Count();
for (int i = 0; i < addCount; i++)
{
var sprite = CreateTriangle();
float triangleHeight = sprite.DrawHeight / DrawHeight;
sprite.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() * (1 + triangleHeight) - triangleHeight : 1);
Add(sprite);
}
}
}
}

View File

@ -56,8 +56,8 @@ namespace osu.Game.Graphics.Containers
{
base.Update();
if (parallaxEnabled)
{
if (parallaxEnabled)
{
Vector2 offset = input.CurrentState.Mouse == null ? Vector2.Zero : ToLocalSpace(input.CurrentState.Mouse.NativeState.Position) - DrawSize / 2;
content.MoveTo(offset * ParallaxAmount, firstUpdate ? 0 : 1000, EasingTypes.OutQuint);
content.Scale = new Vector2(1 + ParallaxAmount);

View File

@ -13,6 +13,7 @@ using osu.Framework.Graphics.OpenGL.Buffers;
using OpenTK.Graphics.ES30;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Colour;
using osu.Framework.Timing;
namespace osu.Game.Graphics.Cursor
{
@ -58,6 +59,9 @@ namespace osu.Game.Graphics.Cursor
public CursorTrail()
{
// as we are currently very dependent on having a running clock, let's make our own clock for the time being.
Clock = new FramedClock();
AlwaysReceiveInput = true;
RelativeSizeAxes = Axes.Both;
@ -231,4 +235,4 @@ namespace osu.Game.Graphics.Cursor
}
}
}
}
}

View File

@ -12,7 +12,6 @@ using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using osu.Game.Configuration;
using System;
namespace osu.Game.Graphics.Cursor
{
@ -116,14 +115,9 @@ namespace osu.Game.Graphics.Cursor
};
cursorScale = config.GetBindable<double>(OsuConfig.GameplayCursorSize);
cursorScale.ValueChanged += scaleChanged;
cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2((float)cursorScale);
cursorScale.TriggerChange();
}
private void scaleChanged(object sender, EventArgs e)
{
cursorContainer.Scale = new Vector2((float)cursorScale);
}
}
}
}

View File

@ -119,14 +119,12 @@ namespace osu.Game.Graphics.Cursor
protected override void PopIn()
{
ActiveCursor.FadeTo(1, 250, EasingTypes.OutQuint);
ActiveCursor.ScaleTo(1, 1000, EasingTypes.OutElastic);
ActiveCursor.ScaleTo(1, 400, EasingTypes.OutQuint);
}
protected override void PopOut()
{
ActiveCursor.FadeTo(0, 1400, EasingTypes.OutQuint);
ActiveCursor.ScaleTo(1.1f, 100, EasingTypes.Out);
ActiveCursor.Delay(100);
ActiveCursor.FadeTo(0, 900, EasingTypes.OutQuint);
ActiveCursor.ScaleTo(0, 500, EasingTypes.In);
}
@ -175,15 +173,10 @@ namespace osu.Game.Graphics.Cursor
};
cursorScale = config.GetBindable<double>(OsuConfig.MenuCursorSize);
cursorScale.ValueChanged += scaleChanged;
cursorScale.ValueChanged += newScale => cursorContainer.Scale = new Vector2((float)newScale);
cursorScale.ValueChanged += newScale => Tooltip.Y = cursorContainer.Height * (float)newScale;
cursorScale.TriggerChange();
}
private void scaleChanged(object sender, EventArgs e)
{
cursorContainer.Scale = new Vector2((float)cursorScale);
Tooltip.Y = cursorContainer.Height * (float)cursorScale;
}
}
}
}

View File

@ -28,7 +28,7 @@ namespace osu.Game.Graphics
/// <param name="easing">The tween easing.</param>
public static void FadeAccent(this IHasAccentColour accentedDrawable, Color4 newColour, double duration = 0, EasingTypes easing = EasingTypes.None)
{
accentedDrawable.TransformTo(accentedDrawable.AccentColour, newColour, duration, easing, new TransformAccent());
accentedDrawable.TransformTo(() => accentedDrawable.AccentColour, newColour, duration, easing, new TransformAccent());
}
}
}

View File

@ -0,0 +1,137 @@
// 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 OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using System;
namespace osu.Game.Graphics.UserInterface
{
public class Bar : Container, IHasAccentColour
{
private readonly Box background;
private readonly Box bar;
private const int resize_duration = 250;
private const EasingTypes easing = EasingTypes.InOutCubic;
private float length;
/// <summary>
/// Length of the bar, ranges from 0 to 1
/// </summary>
public float Length
{
get
{
return length;
}
set
{
length = MathHelper.Clamp(value, 0, 1);
updateBarLength();
}
}
public Color4 BackgroundColour
{
get
{
return background.Colour;
}
set
{
background.Colour = value;
}
}
public Color4 AccentColour
{
get
{
return bar.Colour;
}
set
{
bar.Colour = value;
}
}
private BarDirection direction = BarDirection.LeftToRight;
public BarDirection Direction
{
get
{
return direction;
}
set
{
direction = value;
updateBarLength();
}
}
public Bar()
{
Children = new[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = new Color4(0,0,0,0)
},
bar = new Box
{
RelativeSizeAxes = Axes.Both,
Width = 0,
},
};
}
private void updateBarLength()
{
switch (direction)
{
case BarDirection.LeftToRight:
case BarDirection.RightToLeft:
bar.ResizeTo(new Vector2(length, 1), resize_duration, easing);
break;
case BarDirection.TopToBottom:
case BarDirection.BottomToTop:
bar.ResizeTo(new Vector2(1, length), resize_duration, easing);
break;
}
switch (direction)
{
case BarDirection.LeftToRight:
case BarDirection.TopToBottom:
bar.Anchor = Anchor.TopLeft;
bar.Origin = Anchor.TopLeft;
break;
case BarDirection.RightToLeft:
case BarDirection.BottomToTop:
bar.Anchor = Anchor.BottomRight;
bar.Origin = Anchor.BottomRight;
break;
}
}
}
[Flags]
public enum BarDirection
{
LeftToRight = 1 << 0,
RightToLeft = 1 << 1,
TopToBottom = 1 << 2,
BottomToTop = 1 << 3,
Vertical = TopToBottom | BottomToTop,
Horizontal = LeftToRight | RightToLeft,
}
}

View File

@ -0,0 +1,65 @@
// 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.Graphics;
using osu.Framework.Graphics.Containers;
using System.Collections.Generic;
using System.Linq;
namespace osu.Game.Graphics.UserInterface
{
public class BarGraph : FillFlowContainer<Bar>
{
/// <summary>
/// Manually sets the max value, if null <see cref="Enumerable.Max(IEnumerable{float})"/> is instead used
/// </summary>
public float? MaxValue { get; set; }
private BarDirection direction = BarDirection.BottomToTop;
public new BarDirection Direction
{
get
{
return direction;
}
set
{
direction = value;
base.Direction = (direction & BarDirection.Horizontal) > 0 ? 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.Direction = direction;
}
}
}
/// <summary>
/// A list of floats that defines the length of each <see cref="Bar"/>
/// </summary>
public IEnumerable<float> Values
{
set
{
List<Bar> bars = Children.ToList();
foreach (var bar in value.Select((length, index) => new { Value = length, Bar = bars.Count > index ? bars[index] : null }))
if (bar.Bar != null)
{
bar.Bar.Length = bar.Value / (MaxValue ?? value.Max());
bar.Bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / value.Count()) : new Vector2(1.0f / value.Count(), 1);
}
else
Add(new Bar
{
RelativeSizeAxes = Axes.Both,
Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / value.Count()) : new Vector2(1.0f / value.Count(), 1),
Length = bar.Value / (MaxValue ?? value.Max()),
Direction = Direction,
});
//I'm using ToList() here because Where() returns an Enumerable which can change it's elements afterwards
Remove(Children.Where((bar, index) => index >= value.Count()).ToList());
}
}
}
}

View File

@ -3,8 +3,8 @@
using OpenTK;
using OpenTK.Graphics;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@ -12,18 +12,18 @@ using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface
{
public class Nub : CircularContainer, IStateful<CheckboxState>
public class Nub : CircularContainer, IHasCurrentValue<bool>
{
public const float COLLAPSED_SIZE = 20;
public const float EXPANDED_SIZE = 40;
private readonly Box fill;
private const float border_width = 3;
private Color4 glowingColour, idleColour;
public Nub()
{
Box fill;
Size = new Vector2(COLLAPSED_SIZE, 12);
BorderColour = Color4.White;
@ -40,6 +40,14 @@ namespace osu.Game.Graphics.UserInterface
AlwaysPresent = true,
},
};
Current.ValueChanged += newValue =>
{
if (newValue)
fill.FadeIn(200, EasingTypes.OutQuint);
else
fill.FadeTo(0.01f, 200, EasingTypes.OutQuint); //todo: remove once we figure why containers aren't drawing at all times
};
}
[BackgroundDependencyLoader]
@ -84,28 +92,6 @@ namespace osu.Game.Graphics.UserInterface
}
}
private CheckboxState state;
public CheckboxState State
{
get
{
return state;
}
set
{
state = value;
switch (state)
{
case CheckboxState.Checked:
fill.FadeIn(200, EasingTypes.OutQuint);
break;
case CheckboxState.Unchecked:
fill.FadeTo(0.01f, 200, EasingTypes.OutQuint); //todo: remove once we figure why containers aren't drawing at all times
break;
}
}
}
public Bindable<bool> Current { get; } = new Bindable<bool>();
}
}

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@ -24,18 +23,9 @@ namespace osu.Game.Graphics.UserInterface
{
set
{
if (bindable != null)
bindable.ValueChanged -= bindableValueChanged;
bindable = value;
if (bindable != null)
{
bool state = State == CheckboxState.Checked;
if (state != bindable.Value)
State = bindable.Value ? CheckboxState.Checked : CheckboxState.Unchecked;
bindable.ValueChanged += bindableValueChanged;
}
if (bindable?.Disabled ?? true)
Current.BindTo(bindable);
if (value?.Disabled ?? true)
Alpha = 0.3f;
}
}
@ -84,18 +74,16 @@ namespace osu.Game.Graphics.UserInterface
Margin = new MarginPadding { Right = 5 },
}
};
}
private void bindableValueChanged(object sender, EventArgs e)
{
State = bindable.Value ? CheckboxState.Checked : CheckboxState.Unchecked;
}
nub.Current.BindTo(Current);
protected override void Dispose(bool isDisposing)
{
if (bindable != null)
bindable.ValueChanged -= bindableValueChanged;
base.Dispose(isDisposing);
Current.ValueChanged += newValue =>
{
if (newValue)
sampleChecked?.Play();
else
sampleUnchecked?.Play();
};
}
protected override bool OnHover(InputState state)
@ -118,23 +106,5 @@ namespace osu.Game.Graphics.UserInterface
sampleChecked = audio.Sample.Get(@"Checkbox/check-on");
sampleUnchecked = audio.Sample.Get(@"Checkbox/check-off");
}
protected override void OnChecked()
{
sampleChecked?.Play();
nub.State = CheckboxState.Checked;
if (bindable != null)
bindable.Value = true;
}
protected override void OnUnchecked()
{
sampleUnchecked?.Play();
nub.State = CheckboxState.Unchecked;
if (bindable != null)
bindable.Value = false;
}
}
}

View File

@ -45,7 +45,7 @@ namespace osu.Game.Graphics.UserInterface
private class OsuDropdownMenuItem : DropdownMenuItem<T>
{
public OsuDropdownMenuItem(string text, T value) : base(text, value)
public OsuDropdownMenuItem(string text, T current) : base(text, current)
{
Foreground.Padding = new MarginPadding(2);

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@ -50,7 +49,6 @@ namespace osu.Game.Graphics.UserInterface
nub = new Nub
{
Origin = Anchor.TopCentre,
State = CheckboxState.Unchecked,
Expanded = true,
}
};
@ -64,15 +62,6 @@ namespace osu.Game.Graphics.UserInterface
rightBox.Colour = colours.Pink;
}
private void playSample()
{
if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50)
return;
lastSampleTime = Clock.CurrentTime;
sample.Frequency.Value = 1 + NormalizedValue * 0.2f;
sample.Play();
}
protected override bool OnHover(InputState state)
{
nub.Glowing = true;
@ -85,37 +74,39 @@ namespace osu.Game.Graphics.UserInterface
base.OnHoverLost(state);
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
protected override void OnUserChange()
{
if (args.Key == Key.Left || args.Key == Key.Right)
playSample();
return base.OnKeyDown(state, args);
base.OnUserChange();
playSample();
}
private void playSample()
{
if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50)
return;
lastSampleTime = Clock.CurrentTime;
sample.Frequency.Value = 1 + NormalizedValue * 0.2f;
if (NormalizedValue == 0)
sample.Frequency.Value -= 0.4f;
else if (NormalizedValue == 1)
sample.Frequency.Value += 0.4f;
sample.Play();
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
nub.State = CheckboxState.Checked;
nub.Current.Value = true;
return base.OnMouseDown(state, args);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
nub.State = CheckboxState.Unchecked;
nub.Current.Value = false;
return base.OnMouseUp(state, args);
}
protected override bool OnClick(InputState state)
{
playSample();
return base.OnClick(state);
}
protected override bool OnDrag(InputState state)
{
playSample();
return base.OnDrag(state);
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();

View File

@ -21,7 +21,7 @@ namespace osu.Game.Graphics.UserInterface
{
protected override Dropdown<T> CreateDropdown() => new OsuTabDropdown();
protected override TabItem<T> CreateTabItem(T value) => new OsuTabItem { Value = value };
protected override TabItem<T> CreateTabItem(T value) => new OsuTabItem(value);
protected override bool InternalContains(Vector2 screenSpacePos) => base.InternalContains(screenSpacePos) || Dropdown.Contains(screenSpacePos);
@ -75,16 +75,6 @@ namespace osu.Game.Graphics.UserInterface
}
}
public new T Value
{
get { return base.Value; }
set
{
base.Value = value;
text.Text = (value as Enum)?.GetDescription();
}
}
public override bool Active
{
get { return base.Active; }
@ -134,30 +124,31 @@ namespace osu.Game.Graphics.UserInterface
AccentColour = colours.Blue;
}
public OsuTabItem()
public OsuTabItem(T value) : base(value)
{
AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y;
Children = new Drawable[]
{
text = new OsuSpriteText
{
Margin = new MarginPadding { Top = 5, Bottom = 5 },
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
TextSize = 14,
Font = @"Exo2.0-Bold", // Font should only turn bold when active?
},
box = new Box
{
RelativeSizeAxes = Axes.X,
Height = 1,
Alpha = 0,
Colour = Color4.White,
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
}
text = new OsuSpriteText
{
Margin = new MarginPadding { Top = 5, Bottom = 5 },
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Text = (value as Enum)?.GetDescription(),
TextSize = 14,
Font = @"Exo2.0-Bold", // Font should only turn bold when active?
},
box = new Box
{
RelativeSizeAxes = Axes.X,
Height = 1,
Alpha = 0,
Colour = Color4.White,
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
}
};
}
}

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
@ -24,8 +23,6 @@ namespace osu.Game.Graphics.UserInterface
private readonly SpriteText text;
private readonly TextAwesome icon;
public event EventHandler<CheckboxState> Action;
private Color4? accentColour;
public Color4 AccentColour
{
@ -34,7 +31,7 @@ namespace osu.Game.Graphics.UserInterface
{
accentColour = value;
if (State != CheckboxState.Checked)
if (Current)
{
text.Colour = AccentColour;
icon.Colour = AccentColour;
@ -48,20 +45,6 @@ namespace osu.Game.Graphics.UserInterface
set { text.Text = value; }
}
protected override void OnChecked()
{
fadeIn();
icon.Icon = FontAwesome.fa_check_circle_o;
Action?.Invoke(this, State);
}
protected override void OnUnchecked()
{
fadeOut();
icon.Icon = FontAwesome.fa_circle_o;
Action?.Invoke(this, State);
}
private const float transition_length = 500;
private void fadeIn()
@ -84,7 +67,7 @@ namespace osu.Game.Graphics.UserInterface
protected override void OnHoverLost(InputState state)
{
if (State == CheckboxState.Unchecked)
if (!Current)
fadeOut();
base.OnHoverLost(state);
@ -134,6 +117,20 @@ namespace osu.Game.Graphics.UserInterface
Anchor = Anchor.BottomLeft,
}
};
Current.ValueChanged += v =>
{
if (v)
{
fadeIn();
icon.Icon = FontAwesome.fa_check_circle_o;
}
else
{
fadeOut();
icon.Icon = FontAwesome.fa_circle_o;
}
};
}
}
}

View File

@ -98,21 +98,16 @@ namespace osu.Game.Graphics.UserInterface
DisplayedCount = Current;
Current.ValueChanged += currentChanged;
}
private void currentChanged(object sender, EventArgs e)
{
if (IsLoaded)
TransformCount(displayedCount, Current);
Current.ValueChanged += newValue =>
{
if (IsLoaded) TransformCount(displayedCount, newValue);
};
}
protected override void LoadComplete()
{
base.LoadComplete();
Flush(false, TransformType);
DisplayedCountSpriteText.Text = FormatCount(Current);
DisplayedCountSpriteText.Anchor = Anchor;
DisplayedCountSpriteText.Origin = Origin;
@ -208,8 +203,8 @@ namespace osu.Game.Graphics.UserInterface
? GetProportionalDuration(currentValue, newValue)
: RollingDuration;
transform.StartTime = Time.Current;
transform.EndTime = Time.Current + rollingTotalDuration;
transform.StartTime = TransformStartTime;
transform.EndTime = TransformStartTime + rollingTotalDuration;
transform.StartValue = currentValue;
transform.EndValue = newValue;
transform.Easing = RollingEasing;

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
@ -19,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface.Volume
protected override bool HideOnEscape => false;
private void volumeChanged(object sender, EventArgs e)
private void volumeChanged(double newVolume)
{
Show();
schedulePopOut();