Merge branch 'master' into reduce-panel-width

This commit is contained in:
Dean Herbert 2018-07-17 04:20:40 +09:00 committed by GitHub
commit 4f1b7c8065
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 397 additions and 229 deletions

View File

@ -133,26 +133,26 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
if (ConversionDifficulty > 6.5)
{
if ((convertType & PatternType.LowProbability) > 0)
if (convertType.HasFlag(PatternType.LowProbability))
return generateNRandomNotes(HitObject.StartTime, 0.78, 0.3, 0);
return generateNRandomNotes(HitObject.StartTime, 0.85, 0.36, 0.03);
}
if (ConversionDifficulty > 4)
{
if ((convertType & PatternType.LowProbability) > 0)
if (convertType.HasFlag(PatternType.LowProbability))
return generateNRandomNotes(HitObject.StartTime, 0.43, 0.08, 0);
return generateNRandomNotes(HitObject.StartTime, 0.56, 0.18, 0);
}
if (ConversionDifficulty > 2.5)
{
if ((convertType & PatternType.LowProbability) > 0)
if (convertType.HasFlag(PatternType.LowProbability))
return generateNRandomNotes(HitObject.StartTime, 0.3, 0, 0);
return generateNRandomNotes(HitObject.StartTime, 0.37, 0.08, 0);
}
if ((convertType & PatternType.LowProbability) > 0)
if (convertType.HasFlag(PatternType.LowProbability))
return generateNRandomNotes(HitObject.StartTime, 0.17, 0, 0);
return generateNRandomNotes(HitObject.StartTime, 0.27, 0, 0);
}
@ -209,7 +209,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
var pattern = new Pattern();
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
{
while (PreviousPattern.ColumnHasObject(nextColumn))
nextColumn = Random.Next(RandomStart, TotalColumns);
@ -361,7 +361,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP || sample.Name == SampleInfo.HIT_FINISH;
bool canGenerateTwoNotes = (convertType & PatternType.LowProbability) == 0;
bool canGenerateTwoNotes = !convertType.HasFlag(PatternType.LowProbability);
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample);
if (canGenerateTwoNotes)
@ -391,7 +391,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
int columnRepeat = Math.Min(spanCount, TotalColumns);
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
{
while (PreviousPattern.ColumnHasObject(nextColumn))
nextColumn = Random.Next(RandomStart, TotalColumns);
@ -425,7 +425,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
var pattern = new Pattern();
int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
{
while (PreviousPattern.ColumnHasObject(holdColumn))
holdColumn = Random.Next(RandomStart, TotalColumns);

View File

@ -21,7 +21,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
private readonly PatternType convertType;
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair, IBeatmap originalBeatmap)
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density,
PatternType lastStair, IBeatmap originalBeatmap)
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
{
if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime));
@ -79,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
else
convertType |= PatternType.LowProbability;
if ((convertType & PatternType.KeepSingle) == 0)
if (!convertType.HasFlag(PatternType.KeepSingle))
{
if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8)
convertType |= PatternType.Mirror;
@ -107,7 +108,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0;
if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Any())
if (convertType.HasFlag(PatternType.Reverse) && PreviousPattern.HitObjects.Any())
{
// Generate a new pattern by copying the last hit objects in reverse-column order
for (int i = RandomStart; i < TotalColumns; i++)
@ -117,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
return pattern;
}
if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1
if (convertType.HasFlag(PatternType.Cycle) && PreviousPattern.HitObjects.Count() == 1
// If we convert to 7K + 1, let's not overload the special key
&& (TotalColumns != 8 || lastColumn != 0)
// Make sure the last column was not the centre column
@ -130,7 +131,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
return pattern;
}
if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Any())
if (convertType.HasFlag(PatternType.ForceStack) && PreviousPattern.HitObjects.Any())
{
// Generate a new pattern by placing on the already filled columns
for (int i = RandomStart; i < TotalColumns; i++)
@ -142,7 +143,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
if (PreviousPattern.HitObjects.Count() == 1)
{
if ((convertType & PatternType.Stair) > 0)
if (convertType.HasFlag(PatternType.Stair))
{
// Generate a new pattern by placing on the next column, cycling back to the start if there is no "next"
int targetColumn = lastColumn + 1;
@ -153,7 +154,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
return pattern;
}
if ((convertType & PatternType.ReverseStair) > 0)
if (convertType.HasFlag(PatternType.ReverseStair))
{
// Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous"
int targetColumn = lastColumn - 1;
@ -165,10 +166,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
}
}
if ((convertType & PatternType.KeepSingle) > 0)
if (convertType.HasFlag(PatternType.KeepSingle))
return pattern = generateRandomNotes(1);
if ((convertType & PatternType.Mirror) > 0)
if (convertType.HasFlag(PatternType.Mirror))
{
if (ConversionDifficulty > 6.5)
return pattern = generateRandomPatternWithMirrored(0.12, 0.38, 0.12);
@ -179,21 +180,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
if (ConversionDifficulty > 6.5)
{
if ((convertType & PatternType.LowProbability) > 0)
if (convertType.HasFlag(PatternType.LowProbability))
return pattern = generateRandomPattern(0.78, 0.42, 0, 0);
return pattern = generateRandomPattern(1, 0.62, 0, 0);
}
if (ConversionDifficulty > 4)
{
if ((convertType & PatternType.LowProbability) > 0)
if (convertType.HasFlag(PatternType.LowProbability))
return pattern = generateRandomPattern(0.35, 0.08, 0, 0);
return pattern = generateRandomPattern(0.52, 0.15, 0, 0);
}
if (ConversionDifficulty > 2)
{
if ((convertType & PatternType.LowProbability) > 0)
if (convertType.HasFlag(PatternType.LowProbability))
return pattern = generateRandomPattern(0.18, 0, 0, 0);
return pattern = generateRandomPattern(0.45, 0, 0, 0);
}
@ -204,9 +205,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
foreach (var obj in pattern.HitObjects)
{
if ((convertType & PatternType.Stair) > 0 && obj.Column == TotalColumns - 1)
if (convertType.HasFlag(PatternType.Stair) && obj.Column == TotalColumns - 1)
StairType = PatternType.ReverseStair;
if ((convertType & PatternType.ReverseStair) > 0 && obj.Column == RandomStart)
if (convertType.HasFlag(PatternType.ReverseStair) && obj.Column == RandomStart)
StairType = PatternType.Stair;
}
}
@ -225,7 +226,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
var pattern = new Pattern();
bool allowStacking = (convertType & PatternType.ForceNotStack) == 0;
bool allowStacking = !convertType.HasFlag(PatternType.ForceNotStack);
if (!allowStacking)
noteCount = Math.Min(noteCount, TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects);
@ -235,7 +236,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn) && !allowStacking)
{
if ((convertType & PatternType.Gathered) > 0)
if (convertType.HasFlag(PatternType.Gathered))
{
nextColumn++;
if (nextColumn == TotalColumns)
@ -367,7 +368,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
addToCentre = false;
if ((convertType & PatternType.ForceNotStack) > 0)
if (convertType.HasFlag(PatternType.ForceNotStack))
return getRandomNoteCount(1 / 2f + p2 / 2, p2, (p2 + p3) / 2, p3);
switch (TotalColumns)

View File

@ -25,11 +25,7 @@ namespace osu.Game.Tests.Visual
Children = new[]
{
new NamedIconButton("No change", new IconButton()),
new NamedIconButton("Background colours", new IconButton
{
FlashColour = Color4.DarkGreen,
HoverColour = Color4.Green,
}),
new NamedIconButton("Background colours", new ColouredIconButton()),
new NamedIconButton("Full-width", new IconButton { ButtonSize = new Vector2(200, 30) }),
new NamedIconButton("Unchanging size", new IconButton(), false),
new NamedIconButton("Icon colours", new IconButton
@ -41,6 +37,15 @@ namespace osu.Game.Tests.Visual
};
}
private class ColouredIconButton : IconButton
{
public ColouredIconButton()
{
FlashColour = Color4.DarkGreen;
HoverColour = Color4.Green;
}
}
private class NamedIconButton : Container
{
public NamedIconButton(string name, IconButton button, bool allowSizeChange = true)

View File

@ -45,6 +45,11 @@ namespace osu.Game.Beatmaps
/// </summary>
public event Action<DownloadBeatmapSetRequest> BeatmapDownloadBegan;
/// <summary>
/// Fired when a beatmap download is interrupted, due to user cancellation or other failures.
/// </summary>
public event Action<DownloadBeatmapSetRequest> BeatmapDownloadFailed;
/// <summary>
/// A default representation of a WorkingBeatmap to use when no beatmap is available.
/// </summary>
@ -143,7 +148,7 @@ namespace osu.Game.Beatmaps
return;
}
var downloadNotification = new ProgressNotification
var downloadNotification = new DownloadNotification
{
CompletionText = $"Imported {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}!",
Text = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}",
@ -175,6 +180,8 @@ namespace osu.Game.Beatmaps
request.Failure += error =>
{
BeatmapDownloadFailed?.Invoke(request);
if (error is OperationCanceledException) return;
downloadNotification.State = ProgressNotificationState.Cancelled;
@ -453,5 +460,21 @@ namespace osu.Game.Beatmaps
protected override Texture GetBackground() => null;
protected override Track GetTrack() => null;
}
private class DownloadNotification : ProgressNotification
{
public override bool IsImportant => false;
protected override Notification CreateCompletionNotification() => new SilencedProgressCompletionNotification
{
Activated = CompletionClickAction,
Text = CompletionText
};
private class SilencedProgressCompletionNotification : ProgressCompletionNotification
{
public override bool IsImportant => false;
}
}
}
}

View File

@ -5,6 +5,7 @@ using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Game.Online.API.Requests;
namespace osu.Game.Beatmaps.Drawables
{
@ -19,9 +20,9 @@ namespace osu.Game.Beatmaps.Drawables
private BeatmapManager beatmaps;
/// <summary>
/// Whether the associated beatmap set has been downloading (by this instance or any other instance).
/// Holds the current download state of the beatmap, whether is has already been downloaded, is in progress, or is not downloaded.
/// </summary>
public readonly BindableBool Downloaded = new BindableBool();
public readonly Bindable<DownloadStatus> DownloadState = new Bindable<DownloadStatus>();
public BeatmapSetDownloader(BeatmapSetInfo set, bool noVideo = false)
{
@ -36,10 +37,16 @@ namespace osu.Game.Beatmaps.Drawables
beatmaps.ItemAdded += setAdded;
beatmaps.ItemRemoved += setRemoved;
beatmaps.BeatmapDownloadBegan += downloadBegan;
beatmaps.BeatmapDownloadFailed += downloadFailed;
// initial value
if (set.OnlineBeatmapSetID != null)
Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Any();
if (set.OnlineBeatmapSetID != null && beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Any())
DownloadState.Value = DownloadStatus.Downloaded;
else if (beatmaps.GetExistingDownload(set) != null)
DownloadState.Value = DownloadStatus.Downloading;
else
DownloadState.Value = DownloadStatus.NotDownloaded;
}
protected override void Dispose(bool isDisposing)
@ -50,6 +57,8 @@ namespace osu.Game.Beatmaps.Drawables
{
beatmaps.ItemAdded -= setAdded;
beatmaps.ItemRemoved -= setRemoved;
beatmaps.BeatmapDownloadBegan -= downloadBegan;
beatmaps.BeatmapDownloadFailed -= downloadFailed;
}
}
@ -57,28 +66,45 @@ namespace osu.Game.Beatmaps.Drawables
/// Begin downloading the associated beatmap set.
/// </summary>
/// <returns>True if downloading began. False if an existing download is active or completed.</returns>
public bool Download()
public void Download()
{
if (Downloaded.Value)
return false;
if (beatmaps.GetExistingDownload(set) != null)
return false;
if (DownloadState.Value > DownloadStatus.NotDownloaded)
return;
beatmaps.Download(set, noVideo);
return true;
DownloadState.Value = DownloadStatus.Downloading;
}
private void setAdded(BeatmapSetInfo s)
{
if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
Downloaded.Value = true;
DownloadState.Value = DownloadStatus.Downloaded;
}
private void setRemoved(BeatmapSetInfo s)
{
if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
Downloaded.Value = false;
DownloadState.Value = DownloadStatus.NotDownloaded;
}
private void downloadBegan(DownloadBeatmapSetRequest d)
{
if (d.BeatmapSet.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
DownloadState.Value = DownloadStatus.Downloading;
}
private void downloadFailed(DownloadBeatmapSetRequest d)
{
if (d.BeatmapSet.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
DownloadState.Value = DownloadStatus.NotDownloaded;
}
public enum DownloadStatus
{
NotDownloaded,
Downloading,
Downloaded,
}
}
}

View File

@ -62,28 +62,30 @@ namespace osu.Game.Beatmaps.Formats
protected override void ParseLine(Beatmap beatmap, Section section, string line)
{
var strippedLine = StripComments(line);
switch (section)
{
case Section.General:
handleGeneral(line);
handleGeneral(strippedLine);
return;
case Section.Editor:
handleEditor(line);
handleEditor(strippedLine);
return;
case Section.Metadata:
handleMetadata(line);
return;
case Section.Difficulty:
handleDifficulty(line);
handleDifficulty(strippedLine);
return;
case Section.Events:
handleEvent(line);
handleEvent(strippedLine);
return;
case Section.TimingPoints:
handleTimingPoint(line);
handleTimingPoint(strippedLine);
return;
case Section.HitObjects:
handleHitObject(line);
handleHitObject(strippedLine);
return;
}
@ -305,9 +307,9 @@ namespace osu.Game.Beatmaps.Formats
bool omitFirstBarSignature = false;
if (split.Length >= 8)
{
int effectFlags = int.Parse(split[7]);
kiaiMode = (effectFlags & 1) > 0;
omitFirstBarSignature = (effectFlags & 8) > 0;
EffectFlags effectFlags = (EffectFlags)int.Parse(split[7]);
kiaiMode = effectFlags.HasFlag(EffectFlags.Kiai);
omitFirstBarSignature = effectFlags.HasFlag(EffectFlags.OmitFirstBarLine);
}
string stringSampleSet = sampleSet.ToString().ToLower();
@ -405,5 +407,13 @@ namespace osu.Game.Beatmaps.Formats
private double getOffsetTime() => ApplyOffsets ? offset : 0;
private double getOffsetTime(double time) => time + (ApplyOffsets ? offset : 0);
[Flags]
internal enum EffectFlags
{
None = 0,
Kiai = 1,
OmitFirstBarLine = 8
}
}
}

View File

@ -57,6 +57,8 @@ namespace osu.Game.Beatmaps.Formats
protected virtual void ParseLine(T output, Section section, string line)
{
line = StripComments(line);
switch (section)
{
case Section.Colours:
@ -65,6 +67,14 @@ namespace osu.Game.Beatmaps.Formats
}
}
protected string StripComments(string line)
{
var index = line.IndexOf("//", StringComparison.Ordinal);
if (index > 0)
return line.Substring(0, index);
return line;
}
private bool hasComboColours;
private void handleColours(T output, string line)

View File

@ -42,6 +42,8 @@ namespace osu.Game.Beatmaps.Formats
protected override void ParseLine(Storyboard storyboard, Section section, string line)
{
line = StripComments(line);
switch (section)
{
case Section.Events:

View File

@ -26,10 +26,10 @@ namespace osu.Game.Graphics.UserInterface
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;
}
}
@ -56,14 +56,14 @@ 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,
});

View File

@ -3,31 +3,17 @@
using OpenTK;
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.Input;
using osu.Game.Graphics.Containers;
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>
@ -42,6 +28,7 @@ namespace osu.Game.Graphics.UserInterface
}
private Color4? iconHoverColour;
/// <summary>
/// The icon colour while the <see cref="IconButton"/> is hovered.
/// </summary>
@ -51,20 +38,6 @@ namespace osu.Game.Graphics.UserInterface
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;
}
}
/// <summary>
/// The icon.
/// </summary>
@ -88,93 +61,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),
}
}
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
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);
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(18),
});
}
protected override bool OnHover(InputState state)
{
hover.FadeIn(500, Easing.OutQuint);
icon.FadeColour(IconHoverColour, 500, Easing.OutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
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);
}
}
}

View File

@ -0,0 +1,109 @@
// 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.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Game.Graphics.Containers;
using OpenTK.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 ? Color4.White : colours.Gray9, 200, Easing.OutQuint), true);
}
protected override bool OnHover(InputState state)
{
hover.FadeIn(500, Easing.OutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
hover.FadeOut(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);
}
}
}

View File

@ -56,15 +56,15 @@ namespace osu.Game.Graphics.UserInterface
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);
}

View File

@ -61,20 +61,23 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
Action = () =>
{
if (!downloader.Download())
if (downloader.DownloadState.Value == BeatmapSetDownloader.DownloadStatus.Downloading)
{
Content.MoveToX(-5, 50, Easing.OutSine).Then()
.MoveToX(5, 100, Easing.InOutSine).Then()
.MoveToX(-5, 100, Easing.InOutSine).Then()
.MoveToX(0, 50, Easing.InSine);
return;
}
downloader.Download();
};
downloader.Downloaded.ValueChanged += d =>
downloader.DownloadState.ValueChanged += d =>
{
if (d)
if (d == BeatmapSetDownloader.DownloadStatus.Downloaded)
this.FadeOut(200);
else
else if (d == BeatmapSetDownloader.DownloadStatus.NotDownloaded)
this.FadeIn(200);
};
}

View File

@ -168,11 +168,10 @@ namespace osu.Game.Overlays.Direct
},
new DownloadButton(SetInfo)
{
Size = new Vector2(30),
Size = new Vector2(50, 30),
Margin = new MarginPadding(horizontal_padding),
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Colour = colours.Gray5,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
},
},
},

View File

@ -120,8 +120,8 @@ namespace osu.Game.Overlays.Direct
Alpha = 0,
Child = new DownloadButton(SetInfo)
{
Size = new Vector2(height - vertical_padding * 2),
Margin = new MarginPadding { Left = vertical_padding },
Size = new Vector2(height - vertical_padding * 3),
Margin = new MarginPadding { Left = vertical_padding, Right = vertical_padding },
},
},
new FillFlowContainer

View File

@ -99,6 +99,7 @@ namespace osu.Game.Overlays.Direct
attachDownload(downloadRequest);
beatmaps.BeatmapDownloadBegan += attachDownload;
beatmaps.ItemAdded += setAdded;
}
public override bool DisposeOnDeathRemoval => true;
@ -107,6 +108,7 @@ namespace osu.Game.Overlays.Direct
{
base.Dispose(isDisposing);
beatmaps.BeatmapDownloadBegan -= attachDownload;
beatmaps.ItemAdded -= setAdded;
}
protected override void Update()
@ -171,6 +173,12 @@ namespace osu.Game.Overlays.Direct
};
}
private void setAdded(BeatmapSetInfo s)
{
if (s.OnlineBeatmapSetID == SetInfo.OnlineBeatmapSetID)
progressBar.FadeOut(500);
}
protected override void LoadComplete()
{
base.LoadComplete();

View File

@ -1,76 +1,109 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using OpenTK;
namespace osu.Game.Overlays.Direct
{
public class DownloadButton : OsuClickableContainer
public class DownloadButton : OsuAnimatedButton
{
private readonly SpriteIcon icon;
private readonly SpriteIcon checkmark;
private readonly BeatmapSetDownloader downloader;
private readonly Box background;
private OsuColour colours;
public DownloadButton(BeatmapSetInfo set, bool noVideo = false)
{
BeatmapSetDownloader downloader;
Children = new Drawable[]
AddRange(new Drawable[]
{
downloader = new BeatmapSetDownloader(set, noVideo),
background = new Box
{
RelativeSizeAxes = Axes.Both,
Depth = float.MaxValue
},
icon = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(30),
Icon = FontAwesome.fa_osu_chevron_down_o,
Size = new Vector2(13),
Icon = FontAwesome.fa_download,
},
};
checkmark = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
X = 8,
Size = Vector2.Zero,
Icon = FontAwesome.fa_check,
}
});
Action = () =>
{
if (!downloader.Download())
if (downloader.DownloadState == BeatmapSetDownloader.DownloadStatus.Downloading)
{
// todo: replace with ShakeContainer after https://github.com/ppy/osu/pull/2909 is merged.
Content.MoveToX(-5, 50, Easing.OutSine).Then()
.MoveToX(5, 100, Easing.InOutSine).Then()
.MoveToX(-5, 100, Easing.InOutSine).Then()
.MoveToX(0, 50, Easing.InSine);
}
};
downloader.Downloaded.ValueChanged += d =>
{
if (d)
this.FadeOut(200);
else if (downloader.DownloadState == BeatmapSetDownloader.DownloadStatus.Downloaded)
{
// TODO: Jump to song select with this set when the capability is implemented
}
else
this.FadeIn(200);
{
downloader.Download();
}
};
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
protected override void LoadComplete()
{
icon.ScaleTo(0.9f, 1000, Easing.Out);
return base.OnMouseDown(state, args);
base.LoadComplete();
downloader.DownloadState.BindValueChanged(updateState, true);
FinishTransforms(true);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
[BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuColour colours)
{
icon.ScaleTo(1f, 500, Easing.OutElastic);
return base.OnMouseUp(state, args);
this.colours = colours;
}
protected override bool OnHover(InputState state)
private void updateState(BeatmapSetDownloader.DownloadStatus state)
{
icon.ScaleTo(1.1f, 500, Easing.OutElastic);
return base.OnHover(state);
}
switch (state)
{
case BeatmapSetDownloader.DownloadStatus.NotDownloaded:
background.FadeColour(colours.Gray4, 500, Easing.InOutExpo);
icon.MoveToX(0, 500, Easing.InOutExpo);
checkmark.ScaleTo(Vector2.Zero, 500, Easing.InOutExpo);
break;
protected override void OnHoverLost(InputState state)
{
icon.ScaleTo(1f, 500, Easing.OutElastic);
case BeatmapSetDownloader.DownloadStatus.Downloading:
background.FadeColour(colours.Blue, 500, Easing.InOutExpo);
icon.MoveToX(0, 500, Easing.InOutExpo);
checkmark.ScaleTo(Vector2.Zero, 500, Easing.InOutExpo);
break;
case BeatmapSetDownloader.DownloadStatus.Downloaded:
background.FadeColour(colours.Green, 500, Easing.InOutExpo);
icon.MoveToX(-8, 500, Easing.InOutExpo);
checkmark.ScaleTo(new Vector2(13), 500, Easing.InOutExpo);
break;
}
}
}
}

View File

@ -142,14 +142,14 @@ namespace osu.Game.Overlays
Anchor = Anchor.Centre,
Children = new[]
{
prevButton = new IconButton
prevButton = new MusicIconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = prev,
Icon = FontAwesome.fa_step_backward,
},
playButton = new IconButton
playButton = new MusicIconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -158,7 +158,7 @@ namespace osu.Game.Overlays
Action = play,
Icon = FontAwesome.fa_play_circle_o,
},
nextButton = new IconButton
nextButton = new MusicIconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -167,7 +167,7 @@ namespace osu.Game.Overlays
},
}
},
playlistButton = new IconButton
playlistButton = new MusicIconButton
{
Origin = Anchor.Centre,
Anchor = Anchor.CentreRight,
@ -405,6 +405,16 @@ namespace osu.Game.Overlays
Prev
}
private class MusicIconButton : IconButton
{
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
HoverColour = colours.YellowDark.Opacity(0.6f);
FlashColour = colours.Yellow;
}
}
private class Background : BufferedContainer
{
private readonly Sprite sprite;

View File

@ -128,7 +128,8 @@ namespace osu.Game.Overlays
var section = sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType)));
section?.Add(notification, notification.DisplayOnTop ? -runningDepth : runningDepth);
State = Visibility.Visible;
if (notification.IsImportant)
State = Visibility.Visible;
updateCounts();
});

View File

@ -23,6 +23,11 @@ namespace osu.Game.Overlays.Notifications
/// </summary>
public event Action Closed;
/// <summary>
/// Whether this notification should forcefully display itself.
/// </summary>
public virtual bool IsImportant => true;
/// <summary>
/// Run on user activating the notification. Return true to close.
/// </summary>

View File

@ -118,9 +118,9 @@ namespace osu.Game.Overlays.Toolbar
{
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.Both, //stops us being considered in parent's autosize
Anchor = (TooltipAnchor & Anchor.x0) > 0 ? Anchor.BottomLeft : Anchor.BottomRight,
Anchor = TooltipAnchor.HasFlag(Anchor.x0) ? Anchor.BottomLeft : Anchor.BottomRight,
Origin = TooltipAnchor,
Position = new Vector2((TooltipAnchor & Anchor.x0) > 0 ? 5 : -5, 5),
Position = new Vector2(TooltipAnchor.HasFlag(Anchor.x0) ? 5 : -5, 5),
Alpha = 0,
Children = new[]
{

View File

@ -39,14 +39,14 @@ namespace osu.Game.Rulesets.Objects.Legacy
HitObject result = null;
if ((type & ConvertHitObjectType.Circle) > 0)
if (type.HasFlag(ConvertHitObjectType.Circle))
{
result = CreateHit(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo);
if (split.Length > 5)
readCustomSampleBanks(split[5], bankInfo);
}
else if ((type & ConvertHitObjectType.Slider) > 0)
else if (type.HasFlag(ConvertHitObjectType.Slider))
{
var pos = new Vector2(int.Parse(split[0]), int.Parse(split[1]));
@ -150,14 +150,14 @@ namespace osu.Game.Rulesets.Objects.Legacy
result = CreateSlider(pos, combo, points, length, curveType, repeatCount, nodeSamples);
}
else if ((type & ConvertHitObjectType.Spinner) > 0)
else if (type.HasFlag(ConvertHitObjectType.Spinner))
{
result = CreateSpinner(new Vector2(512, 384) / 2, Convert.ToDouble(split[5], CultureInfo.InvariantCulture) + offset);
if (split.Length > 6)
readCustomSampleBanks(split[6], bankInfo);
}
else if ((type & ConvertHitObjectType.Hold) > 0)
else if (type.HasFlag(ConvertHitObjectType.Hold))
{
// Note: Hold is generated by BMS converts
@ -266,7 +266,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
}
};
if ((type & LegacySoundType.Finish) > 0)
if (type.HasFlag(LegacySoundType.Finish))
{
soundTypes.Add(new SampleInfo
{
@ -276,7 +276,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
});
}
if ((type & LegacySoundType.Whistle) > 0)
if (type.HasFlag(LegacySoundType.Whistle))
{
soundTypes.Add(new SampleInfo
{
@ -286,7 +286,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
});
}
if ((type & LegacySoundType.Clap) > 0)
if (type.HasFlag(LegacySoundType.Clap))
{
soundTypes.Add(new SampleInfo
{

View File

@ -15,10 +15,10 @@ namespace osu.Game.Rulesets.Replays.Legacy
public bool MouseLeft => MouseLeft1 || MouseLeft2;
public bool MouseRight => MouseRight1 || MouseRight2;
public bool MouseLeft1 => (ButtonState & ReplayButtonState.Left1) > 0;
public bool MouseRight1 => (ButtonState & ReplayButtonState.Right1) > 0;
public bool MouseLeft2 => (ButtonState & ReplayButtonState.Left2) > 0;
public bool MouseRight2 => (ButtonState & ReplayButtonState.Right2) > 0;
public bool MouseLeft1 => ButtonState.HasFlag(ReplayButtonState.Left1);
public bool MouseRight1 => ButtonState.HasFlag(ReplayButtonState.Right1);
public bool MouseLeft2 => ButtonState.HasFlag(ReplayButtonState.Left2);
public bool MouseRight2 => ButtonState.HasFlag(ReplayButtonState.Right2);
public ReplayButtonState ButtonState;

View File

@ -27,16 +27,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
public TimelineButton()
{
InternalChild = button = new IconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
IconColour = OsuColour.Gray(0.35f),
IconHoverColour = Color4.White,
HoverColour = OsuColour.Gray(0.25f),
FlashColour = OsuColour.Gray(0.5f),
Action = () => Action?.Invoke()
};
InternalChild = button = new TimelineIconButton { Action = () => Action?.Invoke() };
button.Enabled.BindTo(Enabled);
Width = button.ButtonSize.X;
@ -48,5 +39,18 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
button.ButtonSize = new Vector2(button.ButtonSize.X, DrawHeight);
}
private class TimelineIconButton : IconButton
{
public TimelineIconButton()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
IconColour = OsuColour.Gray(0.35f);
IconHoverColour = Color4.White;
HoverColour = OsuColour.Gray(0.25f);
FlashColour = OsuColour.Gray(0.5f);
}
}
}
}

View File

@ -169,7 +169,7 @@ namespace osu.Game.Screens.Play
OnPause = () =>
{
pauseContainer.Retries = RestartCount;
hudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused;
hudOverlay.KeyCounter.IsCounting = !pauseContainer.IsPaused;
},
OnResume = () => hudOverlay.KeyCounter.IsCounting = true,
Children = new[]
@ -219,9 +219,7 @@ namespace osu.Game.Screens.Play
{
if (!IsCurrentScreen) return;
//we want to hide the hitrenderer immediately (looks better).
//we may be able to remove this once the mouse cursor trail is improved.
RulesetContainer?.Hide();
pauseContainer.Hide();
Restart();
},
}

View File

@ -14,6 +14,8 @@ namespace osu.Game.Skinning
protected override void ParseLine(SkinConfiguration skin, Section section, string line)
{
line = StripComments(line);
switch (section)
{
case Section.General: