mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 12:57:36 +08:00
Merge remote-tracking branch 'origin/master' into UselessToucan/EfCore
# Conflicts: # osu-framework # osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs # osu.Game/Beatmaps/BeatmapInfo.cs # osu.Game/Online/API/Requests/GetBeatmapSetsResponse.cs
This commit is contained in:
commit
b83d7cd4df
23
.vscode/launch.json
vendored
23
.vscode/launch.json
vendored
@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [{
|
||||
"name": "osu! (VisualTests)",
|
||||
"name": "osu! VisualTests (Debug)",
|
||||
"windows": {
|
||||
"type": "clr"
|
||||
},
|
||||
@ -18,7 +18,24 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "osu! (debug)",
|
||||
"name": "osu! VisualTests (Release)",
|
||||
"windows": {
|
||||
"type": "clr"
|
||||
},
|
||||
"type": "mono",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/osu.Game/bin/Release/osu!.exe",
|
||||
"args": [
|
||||
"--tests"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release)",
|
||||
"runtimeExecutable": null,
|
||||
"env": {},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "osu! (Debug)",
|
||||
"windows": {
|
||||
"type": "clr"
|
||||
},
|
||||
@ -32,7 +49,7 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "osu! (release)",
|
||||
"name": "osu! (Release)",
|
||||
"windows": {
|
||||
"type": "clr"
|
||||
},
|
||||
|
1
.vscode/tasks.json
vendored
1
.vscode/tasks.json
vendored
@ -23,6 +23,7 @@
|
||||
},
|
||||
{
|
||||
"taskName": "Build (Release)",
|
||||
"group": "build",
|
||||
"args": [
|
||||
"/property:Configuration=Release"
|
||||
],
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit cdb031c3a8ef693cd71458c5e19c68127ab72938
|
||||
Subproject commit 244775160fd3d9cbb97c70e9213c2e732d65bb0e
|
@ -5,9 +5,9 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
{
|
||||
@ -17,14 +17,37 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
|
||||
protected override IEnumerable<CatchBaseHit> ConvertHitObject(HitObject obj, Beatmap beatmap)
|
||||
{
|
||||
if (!(obj is IHasXPosition))
|
||||
var curveData = obj as IHasCurve;
|
||||
var positionData = obj as IHasPosition;
|
||||
var comboData = obj as IHasCombo;
|
||||
|
||||
if (positionData == null)
|
||||
yield break;
|
||||
|
||||
if (curveData != null)
|
||||
{
|
||||
yield return new JuiceStream
|
||||
{
|
||||
StartTime = obj.StartTime,
|
||||
Samples = obj.Samples,
|
||||
ControlPoints = curveData.ControlPoints,
|
||||
CurveType = curveData.CurveType,
|
||||
Distance = curveData.Distance,
|
||||
RepeatSamples = curveData.RepeatSamples,
|
||||
RepeatCount = curveData.RepeatCount,
|
||||
X = positionData.X / CatchPlayfield.BASE_WIDTH,
|
||||
NewCombo = comboData?.NewCombo ?? false
|
||||
};
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return new Fruit
|
||||
{
|
||||
StartTime = obj.StartTime,
|
||||
NewCombo = (obj as IHasCombo)?.NewCombo ?? false,
|
||||
X = ((IHasXPosition)obj).X / OsuPlayfield.BASE_SIZE.X
|
||||
Samples = obj.Samples,
|
||||
NewCombo = comboData?.NewCombo ?? false,
|
||||
X = positionData.X / CatchPlayfield.BASE_WIDTH
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
// 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.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
public abstract class DrawableCatchHitObject<TObject> : DrawableCatchHitObject
|
||||
where TObject : CatchBaseHit
|
||||
{
|
||||
public new TObject HitObject;
|
||||
|
||||
protected DrawableCatchHitObject(TObject hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
HitObject = hitObject;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class DrawableCatchHitObject : DrawableScrollingHitObject<CatchBaseHit>
|
||||
{
|
||||
protected DrawableCatchHitObject(CatchBaseHit hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
RelativePositionAxes = Axes.Both;
|
||||
X = hitObject.X;
|
||||
Y = (float)HitObject.StartTime;
|
||||
}
|
||||
|
||||
public Func<CatchBaseHit, bool> CheckPosition;
|
||||
|
||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||
{
|
||||
if (timeOffset > 0)
|
||||
AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss });
|
||||
}
|
||||
|
||||
private const float preempt = 1000;
|
||||
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
using (BeginAbsoluteSequence(HitObject.StartTime - preempt))
|
||||
{
|
||||
// animation
|
||||
this.FadeIn(200);
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Miss:
|
||||
using (BeginAbsoluteSequence(HitObject.StartTime, true))
|
||||
this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
34
osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs
Normal file
34
osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2007-2017 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.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
public class DrawableDroplet : DrawableCatchHitObject<Droplet>
|
||||
{
|
||||
public DrawableDroplet(Droplet h)
|
||||
: base(h)
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Size = new Vector2(Pulp.PULP_SIZE);
|
||||
|
||||
AccentColour = h.ComboColour;
|
||||
Masking = false;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Child = new Pulp
|
||||
{
|
||||
AccentColour = AccentColour,
|
||||
Scale = new Vector2(0.8f),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,72 +1,29 @@
|
||||
// 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.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
public class DrawableFruit : DrawableScrollingHitObject<CatchBaseHit>
|
||||
public class DrawableFruit : DrawableCatchHitObject<Fruit>
|
||||
{
|
||||
private const float pulp_size = 20;
|
||||
|
||||
private class Pulp : Circle, IHasAccentColour
|
||||
{
|
||||
public Pulp()
|
||||
{
|
||||
Size = new Vector2(pulp_size);
|
||||
|
||||
Blending = BlendingMode.Additive;
|
||||
Colour = Color4.White.Opacity(0.9f);
|
||||
}
|
||||
|
||||
private Color4 accentColour;
|
||||
public Color4 AccentColour
|
||||
{
|
||||
get { return accentColour; }
|
||||
set
|
||||
{
|
||||
accentColour = value;
|
||||
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Radius = 5,
|
||||
Colour = accentColour.Lighten(100),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DrawableFruit(CatchBaseHit h)
|
||||
public DrawableFruit(Fruit h)
|
||||
: base(h)
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f);
|
||||
|
||||
RelativePositionAxes = Axes.Both;
|
||||
X = h.X;
|
||||
|
||||
Size = new Vector2(Pulp.PULP_SIZE * 2.2f, Pulp.PULP_SIZE * 2.8f);
|
||||
AccentColour = HitObject.ComboColour;
|
||||
|
||||
Masking = false;
|
||||
|
||||
Rotation = (float)(RNG.NextDouble() - 0.5f) * 40;
|
||||
}
|
||||
|
||||
public Func<CatchBaseHit, bool> CheckPosition;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@ -114,30 +71,5 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private const float preempt = 1000;
|
||||
|
||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||
{
|
||||
if (timeOffset > 0)
|
||||
AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss });
|
||||
}
|
||||
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
using (BeginAbsoluteSequence(HitObject.StartTime - preempt))
|
||||
{
|
||||
// animation
|
||||
this.FadeIn(200);
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Miss:
|
||||
using (BeginAbsoluteSequence(HitObject.StartTime, true))
|
||||
this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using OpenTK;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
public class DrawableJuiceStream : DrawableCatchHitObject<JuiceStream>
|
||||
{
|
||||
private readonly Container dropletContainer;
|
||||
|
||||
public DrawableJuiceStream(JuiceStream s) : base(s)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Height = (float)HitObject.Duration;
|
||||
X = 0;
|
||||
|
||||
Child = dropletContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime),
|
||||
RelativeChildSize = new Vector2(1, (float)HitObject.Duration)
|
||||
};
|
||||
|
||||
foreach (CatchBaseHit tick in s.Ticks)
|
||||
{
|
||||
TinyDroplet tiny = tick as TinyDroplet;
|
||||
if (tiny != null)
|
||||
{
|
||||
AddNested(new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) });
|
||||
continue;
|
||||
}
|
||||
|
||||
Droplet droplet = tick as Droplet;
|
||||
if (droplet != null)
|
||||
AddNested(new DrawableDroplet(droplet));
|
||||
|
||||
Fruit fruit = tick as Fruit;
|
||||
if (fruit != null)
|
||||
AddNested(new DrawableFruit(fruit));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void AddNested(DrawableHitObject<CatchBaseHit> h)
|
||||
{
|
||||
((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false;
|
||||
dropletContainer.Add(h);
|
||||
base.AddNested(h);
|
||||
}
|
||||
}
|
||||
}
|
43
osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs
Normal file
43
osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
|
||||
{
|
||||
public class Pulp : Circle, IHasAccentColour
|
||||
{
|
||||
public const float PULP_SIZE = 20;
|
||||
|
||||
public Pulp()
|
||||
{
|
||||
Size = new Vector2(PULP_SIZE);
|
||||
|
||||
Blending = BlendingMode.Additive;
|
||||
Colour = Color4.White.Opacity(0.9f);
|
||||
}
|
||||
|
||||
private Color4 accentColour;
|
||||
public Color4 AccentColour
|
||||
{
|
||||
get { return accentColour; }
|
||||
set
|
||||
{
|
||||
accentColour = value;
|
||||
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Radius = 5,
|
||||
Colour = accentColour.Lighten(100),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
169
osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
Normal file
169
osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
Normal file
@ -0,0 +1,169 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using OpenTK;
|
||||
using osu.Framework.Lists;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects
|
||||
{
|
||||
public class JuiceStream : CatchBaseHit, IHasCurve
|
||||
{
|
||||
/// <summary>
|
||||
/// Positional distance that results in a duration of one second, before any speed adjustments.
|
||||
/// </summary>
|
||||
private const float base_scoring_distance = 100;
|
||||
|
||||
public readonly SliderCurve Curve = new SliderCurve();
|
||||
|
||||
public int RepeatCount { get; set; } = 1;
|
||||
|
||||
public double Velocity;
|
||||
public double TickDistance;
|
||||
|
||||
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
||||
{
|
||||
base.ApplyDefaults(controlPointInfo, difficulty);
|
||||
|
||||
TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
|
||||
DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime);
|
||||
|
||||
double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier;
|
||||
|
||||
Velocity = scoringDistance / timingPoint.BeatLength;
|
||||
TickDistance = scoringDistance / difficulty.SliderTickRate;
|
||||
}
|
||||
|
||||
public IEnumerable<CatchBaseHit> Ticks
|
||||
{
|
||||
get
|
||||
{
|
||||
SortedList<CatchBaseHit> ticks = new SortedList<CatchBaseHit>((a, b) => a.StartTime.CompareTo(b.StartTime));
|
||||
|
||||
if (TickDistance == 0)
|
||||
return ticks;
|
||||
|
||||
var length = Curve.Distance;
|
||||
var tickDistance = Math.Min(TickDistance, length);
|
||||
var repeatDuration = length / Velocity;
|
||||
|
||||
var minDistanceFromEnd = Velocity * 0.01;
|
||||
|
||||
ticks.Add(new Fruit
|
||||
{
|
||||
Samples = Samples,
|
||||
ComboColour = ComboColour,
|
||||
StartTime = StartTime,
|
||||
X = X
|
||||
});
|
||||
|
||||
for (var repeat = 0; repeat < RepeatCount; repeat++)
|
||||
{
|
||||
var repeatStartTime = StartTime + repeat * repeatDuration;
|
||||
var reversed = repeat % 2 == 1;
|
||||
|
||||
for (var d = tickDistance; d <= length; d += tickDistance)
|
||||
{
|
||||
if (d > length - minDistanceFromEnd)
|
||||
break;
|
||||
|
||||
var timeProgress = d / length;
|
||||
var distanceProgress = reversed ? 1 - timeProgress : timeProgress;
|
||||
|
||||
var lastTickTime = repeatStartTime + timeProgress * repeatDuration;
|
||||
ticks.Add(new Droplet
|
||||
{
|
||||
StartTime = lastTickTime,
|
||||
ComboColour = ComboColour,
|
||||
X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH,
|
||||
Samples = new SampleInfoList(Samples.Select(s => new SampleInfo
|
||||
{
|
||||
Bank = s.Bank,
|
||||
Name = @"slidertick",
|
||||
Volume = s.Volume
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
double tinyTickInterval = tickDistance / length * repeatDuration;
|
||||
while (tinyTickInterval > 100)
|
||||
tinyTickInterval /= 2;
|
||||
|
||||
for (double t = 0; t < repeatDuration; t += tinyTickInterval)
|
||||
{
|
||||
double progress = reversed ? 1 - t / repeatDuration : t / repeatDuration;
|
||||
|
||||
ticks.Add(new TinyDroplet
|
||||
{
|
||||
StartTime = repeatStartTime + t,
|
||||
ComboColour = ComboColour,
|
||||
X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH,
|
||||
Samples = new SampleInfoList(Samples.Select(s => new SampleInfo
|
||||
{
|
||||
Bank = s.Bank,
|
||||
Name = @"slidertick",
|
||||
Volume = s.Volume
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
ticks.Add(new Fruit
|
||||
{
|
||||
Samples = Samples,
|
||||
ComboColour = ComboColour,
|
||||
StartTime = repeatStartTime + repeatDuration,
|
||||
X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
|
||||
});
|
||||
}
|
||||
|
||||
return ticks;
|
||||
}
|
||||
}
|
||||
|
||||
public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity;
|
||||
|
||||
public float EndX => Curve.PositionAt(ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH;
|
||||
|
||||
public double Duration => EndTime - StartTime;
|
||||
|
||||
public double Distance
|
||||
{
|
||||
get { return Curve.Distance; }
|
||||
set { Curve.Distance = value; }
|
||||
}
|
||||
|
||||
public List<Vector2> ControlPoints
|
||||
{
|
||||
get { return Curve.ControlPoints; }
|
||||
set { Curve.ControlPoints = value; }
|
||||
}
|
||||
|
||||
public List<SampleInfoList> RepeatSamples { get; set; } = new List<SampleInfoList>();
|
||||
|
||||
public CurveType CurveType
|
||||
{
|
||||
get { return Curve.CurveType; }
|
||||
set { Curve.CurveType = value; }
|
||||
}
|
||||
|
||||
public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress));
|
||||
|
||||
public double ProgressAt(double progress)
|
||||
{
|
||||
double p = progress * RepeatCount % 1;
|
||||
if (RepeatAt(progress) % 2 == 1)
|
||||
p = 1 - p;
|
||||
return p;
|
||||
}
|
||||
|
||||
public int RepeatAt(double progress) => (int)(progress * RepeatCount);
|
||||
}
|
||||
}
|
9
osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
Normal file
9
osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects
|
||||
{
|
||||
public class TinyDroplet : Droplet
|
||||
{
|
||||
}
|
||||
}
|
@ -21,6 +21,19 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
||||
{
|
||||
foreach (var obj in beatmap.HitObjects)
|
||||
{
|
||||
var stream = obj as JuiceStream;
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
|
||||
foreach (var unused in stream.Ticks)
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var fruit = obj as Fruit;
|
||||
|
||||
if (fruit != null)
|
||||
|
@ -2,8 +2,6 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
@ -13,15 +11,5 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
public TestCaseCatchPlayer() : base(typeof(CatchRuleset))
|
||||
{
|
||||
}
|
||||
|
||||
protected override Beatmap CreateBeatmap()
|
||||
{
|
||||
var beatmap = new Beatmap();
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
beatmap.HitObjects.Add(new Fruit { X = 0.5f, StartTime = i * 100, NewCombo = i % 8 == 0 });
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs
Normal file
27
osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer
|
||||
{
|
||||
public TestCaseCatchStacker() : base(typeof(CatchRuleset))
|
||||
{
|
||||
}
|
||||
|
||||
protected override Beatmap CreateBeatmap()
|
||||
{
|
||||
var beatmap = new Beatmap();
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
beatmap.HitObjects.Add(new Fruit { X = 0.5f, StartTime = i * 100, NewCombo = i % 8 == 0 });
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
public class CatchPlayfield : ScrollingPlayfield
|
||||
{
|
||||
public static readonly float BASE_WIDTH = 512;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
private readonly Container<Drawable> content;
|
||||
|
||||
@ -28,8 +30,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
Reversed.Value = true;
|
||||
|
||||
Size = new Vector2(1);
|
||||
|
||||
Anchor = Anchor.TopCentre;
|
||||
Origin = Anchor.TopCentre;
|
||||
|
||||
@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
base.Add(h);
|
||||
|
||||
var fruit = (DrawableFruit)h;
|
||||
var fruit = (DrawableCatchHitObject)h;
|
||||
fruit.CheckPosition = CheckIfWeCanCatch;
|
||||
}
|
||||
|
||||
@ -83,7 +83,11 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
if (judgement.IsHit)
|
||||
{
|
||||
Vector2 screenPosition = judgedObject.ScreenSpaceDrawQuad.Centre;
|
||||
Remove(judgedObject);
|
||||
|
||||
// todo: don't do this
|
||||
(judgedObject.Parent as Container<DrawableHitObject>)?.Remove(judgedObject);
|
||||
(judgedObject.Parent as Container)?.Remove(judgedObject);
|
||||
|
||||
catcher.Add(judgedObject, screenPosition);
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,13 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
protected override DrawableHitObject<CatchBaseHit> GetVisualRepresentation(CatchBaseHit h)
|
||||
{
|
||||
if (h is Fruit)
|
||||
return new DrawableFruit(h);
|
||||
var fruit = h as Fruit;
|
||||
if (fruit != null)
|
||||
return new DrawableFruit(fruit);
|
||||
|
||||
var stream = h as JuiceStream;
|
||||
if (stream != null)
|
||||
return new DrawableJuiceStream(stream);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -50,14 +50,21 @@
|
||||
<Compile Include="Beatmaps\CatchBeatmapProcessor.cs" />
|
||||
<Compile Include="CatchDifficultyCalculator.cs" />
|
||||
<Compile Include="CatchInputManager.cs" />
|
||||
<Compile Include="Objects\Drawable\DrawableCatchHitObject.cs" />
|
||||
<Compile Include="Objects\Drawable\DrawableDroplet.cs" />
|
||||
<Compile Include="Objects\Drawable\DrawableJuiceStream.cs" />
|
||||
<Compile Include="Objects\Drawable\Pieces\Pulp.cs" />
|
||||
<Compile Include="Objects\JuiceStream.cs" />
|
||||
<Compile Include="Scoring\CatchScoreProcessor.cs" />
|
||||
<Compile Include="Judgements\CatchJudgement.cs" />
|
||||
<Compile Include="Objects\CatchBaseHit.cs" />
|
||||
<Compile Include="Objects\Drawable\DrawableFruit.cs" />
|
||||
<Compile Include="Objects\Droplet.cs" />
|
||||
<Compile Include="Objects\Fruit.cs" />
|
||||
<Compile Include="Objects\TinyDroplet.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Tests\TestCaseCatcher.cs" />
|
||||
<Compile Include="Tests\TestCaseCatchStacker.cs" />
|
||||
<Compile Include="Tests\TestCaseCatchPlayer.cs" />
|
||||
<Compile Include="UI\Catcher.cs" />
|
||||
<Compile Include="UI\CatchRulesetContainer.cs" />
|
||||
@ -79,11 +86,6 @@
|
||||
<Name>osu.Framework</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj">
|
||||
<Project>{C92A607B-1FDD-4954-9F92-03FF547D9080}</Project>
|
||||
<Name>osu.Game.Rulesets.Osu</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
|
||||
<Project>{2a66dd92-adb1-4994-89e2-c94e04acda0d}</Project>
|
||||
<Name>osu.Game</Name>
|
||||
|
@ -22,6 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
private readonly SpinnerDisc disc;
|
||||
private readonly SpinnerTicks ticks;
|
||||
private readonly SpinnerSpmCounter spmCounter;
|
||||
|
||||
private readonly Container mainContainer;
|
||||
|
||||
@ -103,6 +104,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
},
|
||||
}
|
||||
},
|
||||
spmCounter = new SpinnerSpmCounter
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Y = 120,
|
||||
Alpha = 0
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -157,6 +165,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
protected override void Update()
|
||||
{
|
||||
disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton);
|
||||
if (!spmCounter.IsPresent && disc.Tracking)
|
||||
spmCounter.FadeIn(TIME_FADEIN);
|
||||
|
||||
base.Update();
|
||||
}
|
||||
@ -167,6 +177,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
circle.Rotation = disc.Rotation;
|
||||
ticks.Rotation = disc.Rotation;
|
||||
spmCounter.SetRotation(disc.RotationAbsolute);
|
||||
|
||||
float relativeCircleScale = spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
|
||||
disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint);
|
||||
|
@ -77,7 +77,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
private float lastAngle;
|
||||
private float currentRotation;
|
||||
public float RotationAbsolute;
|
||||
|
||||
private int completeTick;
|
||||
|
||||
private bool updateCompleteTick() => completeTick != (completeTick = (int)(RotationAbsolute / 360));
|
||||
|
@ -0,0 +1,75 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
{
|
||||
public class SpinnerSpmCounter : Container
|
||||
{
|
||||
private readonly OsuSpriteText spmText;
|
||||
|
||||
public SpinnerSpmCounter()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
spmText = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = @"0",
|
||||
Font = @"Venera",
|
||||
TextSize = 24
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = @"SPINS PER MINUTE",
|
||||
Font = @"Venera",
|
||||
TextSize = 12,
|
||||
Y = 30
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private double spm;
|
||||
|
||||
public double SpinsPerMinute
|
||||
{
|
||||
get { return spm; }
|
||||
private set
|
||||
{
|
||||
if (value == spm) return;
|
||||
spm = value;
|
||||
spmText.Text = Math.Truncate(value).ToString(@"#0");
|
||||
}
|
||||
}
|
||||
|
||||
private struct RotationRecord
|
||||
{
|
||||
public float Rotation;
|
||||
public double Time;
|
||||
}
|
||||
|
||||
private readonly Queue<RotationRecord> records = new Queue<RotationRecord>();
|
||||
private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues
|
||||
|
||||
public void SetRotation(float currentRotation)
|
||||
{
|
||||
if (records.Count > 0)
|
||||
{
|
||||
var record = records.Peek();
|
||||
while (records.Count > 0 && Time.Current - records.Peek().Time > spm_count_duration)
|
||||
record = records.Dequeue();
|
||||
SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360;
|
||||
}
|
||||
|
||||
records.Enqueue(new RotationRecord { Rotation = currentRotation, Time = Time.Current });
|
||||
}
|
||||
}
|
||||
}
|
@ -68,6 +68,7 @@
|
||||
<Compile Include="Objects\Drawables\Pieces\RingPiece.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\SliderBouncer.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\SpinnerDisc.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\SpinnerSpmCounter.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\SpinnerTicks.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\TrianglesPiece.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\SliderBall.cs" />
|
||||
|
@ -117,19 +117,27 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
//ensure we were stored to beatmap database backing...
|
||||
Assert.IsTrue(resultSets.Count() == 1, $@"Incorrect result count found ({resultSets.Count()} but should be 1).");
|
||||
|
||||
IEnumerable<BeatmapInfo> resultBeatmaps = null;
|
||||
Func<IEnumerable<BeatmapInfo>> queryBeatmaps = () => store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0);
|
||||
Func<IEnumerable<BeatmapSetInfo>> queryBeatmapSets = () => store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526);
|
||||
|
||||
//if we don't re-check here, the set will be inserted but the beatmaps won't be present yet.
|
||||
waitForOrAssert(() => (resultBeatmaps = store.QueryBeatmaps(s => s.BeatmapSetOnlineInfoId == 241526 && s.BeatmapDifficultyId > 0)).Count() == 12,
|
||||
waitForOrAssert(() => queryBeatmaps().Count() == 12,
|
||||
@"Beatmaps did not import to the database in allocated time", timeout);
|
||||
|
||||
var set = store.QueryBeatmapSets(s => s.BeatmapSetOnlineInfoId == 241526).First();
|
||||
waitForOrAssert(() => queryBeatmapSets().Count() == 1,
|
||||
@"BeatmapSet did not import to the database in allocated time", timeout);
|
||||
|
||||
Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(),
|
||||
$@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count}).");
|
||||
int countBeatmapSetBeatmaps = 0;
|
||||
int countBeatmaps = 0;
|
||||
|
||||
foreach (BeatmapInfo b in resultBeatmaps)
|
||||
Assert.IsTrue(set.Beatmaps.Any(c => c.BeatmapOnlineInfoId == b.BeatmapOnlineInfoId));
|
||||
waitForOrAssert(() =>
|
||||
(countBeatmapSetBeatmaps = queryBeatmapSets().First().Beatmaps.Count) ==
|
||||
(countBeatmaps = queryBeatmaps().Count()),
|
||||
$@"Incorrect database beatmap count post-import ({countBeatmaps} but should be {countBeatmapSetBeatmaps}).", timeout);
|
||||
|
||||
var set = queryBeatmapSets().First();
|
||||
|
||||
foreach (BeatmapInfo b in set.Beatmaps)
|
||||
|
||||
Assert.IsTrue(set.Beatmaps.Count > 0);
|
||||
|
||||
|
@ -19,9 +19,11 @@ namespace osu.Game.Beatmaps
|
||||
//TODO: should be in database
|
||||
public int BeatmapVersion;
|
||||
|
||||
[JsonProperty("id")]
|
||||
[NotMapped]
|
||||
public int? BeatmapOnlineInfoId { get; set; }
|
||||
|
||||
[JsonProperty("beatmapset_id")]
|
||||
[NotMapped]
|
||||
public int? BeatmapSetOnlineInfoId { get; set; }
|
||||
|
||||
|
@ -536,7 +536,7 @@ namespace osu.Game.Beatmaps
|
||||
catch { return null; }
|
||||
}
|
||||
|
||||
private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => f.Filename == filename).FileInfo.StoragePath;
|
||||
private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => string.Equals(f.Filename, filename, StringComparison.InvariantCultureIgnoreCase)).FileInfo.StoragePath;
|
||||
|
||||
protected override Texture GetBackground()
|
||||
{
|
||||
@ -559,6 +559,8 @@ namespace osu.Game.Beatmaps
|
||||
}
|
||||
catch { return new TrackVirtual(); }
|
||||
}
|
||||
|
||||
protected override Waveform GetWaveform() => new Waveform(store.GetStream(getPathForFile(Metadata.AudioFile)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -611,9 +611,9 @@ namespace osu.Game.Beatmaps.Formats
|
||||
CommandTimelineGroup timelineGroup = null;
|
||||
|
||||
string line;
|
||||
while ((line = stream.ReadLine()?.Trim()) != null)
|
||||
while ((line = stream.ReadLine()) != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(line))
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith("//"))
|
||||
@ -679,10 +679,12 @@ namespace osu.Game.Beatmaps.Formats
|
||||
|
||||
private KeyValuePair<string, string> splitKeyVal(string line, char separator)
|
||||
{
|
||||
var split = line.Trim().Split(new[] { separator }, 2);
|
||||
|
||||
return new KeyValuePair<string, string>
|
||||
(
|
||||
line.Remove(line.IndexOf(separator)).Trim(),
|
||||
line.Substring(line.IndexOf(separator) + 1).Trim()
|
||||
split[0].Trim(),
|
||||
split.Length > 1 ? split[1].Trim() : string.Empty
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ namespace osu.Game.Beatmaps
|
||||
protected abstract Beatmap GetBeatmap();
|
||||
protected abstract Texture GetBackground();
|
||||
protected abstract Track GetTrack();
|
||||
protected virtual Waveform GetWaveform() => new Waveform();
|
||||
|
||||
private Beatmap beatmap;
|
||||
private readonly object beatmapLock = new object();
|
||||
@ -96,6 +97,17 @@ namespace osu.Game.Beatmaps
|
||||
}
|
||||
}
|
||||
|
||||
private Waveform waveform;
|
||||
private readonly object waveformLock = new object();
|
||||
public Waveform Waveform
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (waveformLock)
|
||||
return waveform ?? (waveform = GetWaveform());
|
||||
}
|
||||
}
|
||||
|
||||
public bool TrackLoaded => track != null;
|
||||
|
||||
public void TransferTo(WorkingBeatmap other)
|
||||
@ -114,6 +126,8 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
background?.Dispose();
|
||||
background = null;
|
||||
|
||||
waveform?.Dispose();
|
||||
}
|
||||
|
||||
public void DisposeTrack()
|
||||
|
33
osu.Game/Graphics/Containers/OsuHoverContainer.cs
Normal file
33
osu.Game/Graphics/Containers/OsuHoverContainer.cs
Normal file
@ -0,0 +1,33 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input;
|
||||
|
||||
namespace osu.Game.Graphics.Containers
|
||||
{
|
||||
public class OsuHoverContainer : OsuClickableContainer
|
||||
{
|
||||
private Color4 hoverColour;
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
this.FadeColour(hoverColour, 500, Easing.OutQuint);
|
||||
return base.OnHover(state);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
this.FadeColour(Color4.White, 500, Easing.OutQuint);
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
hoverColour = colours.Yellow;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
// 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.Containers;
|
||||
using OpenTK;
|
||||
using osu.Framework.Graphics;
|
||||
|
||||
namespace osu.Game.Graphics.Processing
|
||||
{
|
||||
internal class RatioAdjust : Container
|
||||
{
|
||||
public RatioAdjust()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
Vector2 parent = Parent.DrawSize;
|
||||
|
||||
Scale = new Vector2(Math.Min(parent.Y / 768f, parent.X / 1024f));
|
||||
Size = new Vector2(1 / Scale.X);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,32 +15,91 @@ namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public class IconButton : OsuClickableContainer
|
||||
{
|
||||
private readonly SpriteIcon icon;
|
||||
private readonly Box hover;
|
||||
private readonly Container content;
|
||||
private 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; }
|
||||
set
|
||||
{
|
||||
iconColour = value;
|
||||
icon.Colour = value;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The icon.
|
||||
/// </summary>
|
||||
public FontAwesome Icon
|
||||
{
|
||||
get { return icon.Icon; }
|
||||
set { icon.Icon = value; }
|
||||
}
|
||||
|
||||
private const float button_size = 30;
|
||||
private Color4 flashColour;
|
||||
|
||||
/// <summary>
|
||||
/// The icon scale. This does not affect <see cref="IconButton.Scale"/>.
|
||||
/// </summary>
|
||||
public Vector2 IconScale
|
||||
{
|
||||
get { return icon.Scale; }
|
||||
set { icon.Scale = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The size of the <see cref="IconButton"/> while it is not being pressed.
|
||||
/// </summary>
|
||||
public Vector2 ButtonSize
|
||||
{
|
||||
get { return content.Size; }
|
||||
set { content.Size = value; }
|
||||
}
|
||||
|
||||
private readonly Container content;
|
||||
private readonly SpriteIcon icon;
|
||||
private readonly Box hover;
|
||||
|
||||
public IconButton()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Origin = Anchor.Centre;
|
||||
Anchor = Anchor.Centre;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
content = new Container
|
||||
@ -48,7 +107,6 @@ namespace osu.Game.Graphics.UserInterface
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Size = new Vector2(button_size),
|
||||
|
||||
CornerRadius = 5,
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
@ -78,8 +136,11 @@ namespace osu.Game.Graphics.UserInterface
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
hover.Colour = colours.Yellow.Opacity(0.6f);
|
||||
flashColour = colours.Yellow;
|
||||
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);
|
||||
}
|
||||
@ -87,18 +148,20 @@ namespace osu.Game.Graphics.UserInterface
|
||||
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);
|
||||
hover.FlashColour(FlashColour, 800, Easing.OutQuint);
|
||||
return base.OnClick(state);
|
||||
}
|
||||
|
||||
|
17
osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs
Normal file
17
osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetBeatmapSetRequest : APIRequest<GetBeatmapSetsResponse>
|
||||
{
|
||||
private readonly int beatmapSetId;
|
||||
|
||||
public GetBeatmapSetRequest(int beatmapSetId)
|
||||
{
|
||||
this.beatmapSetId = beatmapSetId;
|
||||
}
|
||||
|
||||
protected override string Target => $@"beatmapsets/{beatmapSetId}";
|
||||
}
|
||||
}
|
@ -5,34 +5,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Direct;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetBeatmapSetsRequest : APIRequest<IEnumerable<GetBeatmapSetsResponse>>
|
||||
{
|
||||
private readonly string query;
|
||||
private readonly RulesetInfo ruleset;
|
||||
private readonly RankStatus rankStatus;
|
||||
private readonly DirectSortCriteria sortCriteria;
|
||||
private readonly SortDirection direction;
|
||||
private string directionString => direction == SortDirection.Descending ? @"desc" : @"asc";
|
||||
|
||||
public GetBeatmapSetsRequest(string query, RulesetInfo ruleset, RankStatus rankStatus = RankStatus.Any, DirectSortCriteria sortCriteria = DirectSortCriteria.Ranked, SortDirection direction = SortDirection.Descending)
|
||||
{
|
||||
this.query = System.Uri.EscapeDataString(query);
|
||||
this.ruleset = ruleset;
|
||||
this.rankStatus = rankStatus;
|
||||
this.sortCriteria = sortCriteria;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.Id ?? 0}&s={(int)rankStatus}&sort={sortCriteria.ToString().ToLower()}_{directionString}";
|
||||
}
|
||||
|
||||
public class GetBeatmapSetsResponse : BeatmapMetadata
|
||||
{
|
||||
[JsonProperty(@"covers")]
|
||||
@ -51,7 +28,7 @@ namespace osu.Game.Online.API.Requests
|
||||
private int onlineId { get; set; }
|
||||
|
||||
[JsonProperty(@"creator")]
|
||||
private string creatorUsername;
|
||||
private string creatorUsername { get; set; }
|
||||
|
||||
[JsonProperty(@"user_id")]
|
||||
private long creatorId = 1;
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Users;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -67,6 +68,9 @@ namespace osu.Game.Online.API.Requests
|
||||
set { Replay = value; }
|
||||
}
|
||||
|
||||
[JsonProperty(@"mode_int")]
|
||||
public int OnlineRulesetID { get; set; }
|
||||
|
||||
[JsonProperty(@"score_id")]
|
||||
private long onlineScoreID
|
||||
{
|
||||
@ -79,6 +83,18 @@ namespace osu.Game.Online.API.Requests
|
||||
set { Date = value; }
|
||||
}
|
||||
|
||||
[JsonProperty(@"beatmap")]
|
||||
private BeatmapInfo beatmap
|
||||
{
|
||||
set { Beatmap = value; }
|
||||
}
|
||||
|
||||
[JsonProperty(@"beatmapset")]
|
||||
private BeatmapMetadata metadata
|
||||
{
|
||||
set { Beatmap.Metadata = value; }
|
||||
}
|
||||
|
||||
[JsonProperty(@"statistics")]
|
||||
private Dictionary<string, object> jsonStats
|
||||
{
|
||||
@ -116,7 +132,12 @@ namespace osu.Game.Online.API.Requests
|
||||
public void ApplyBeatmap(BeatmapInfo beatmap)
|
||||
{
|
||||
Beatmap = beatmap;
|
||||
Ruleset = beatmap.Ruleset;
|
||||
ApplyRuleset(beatmap.Ruleset);
|
||||
}
|
||||
|
||||
public void ApplyRuleset(RulesetInfo ruleset)
|
||||
{
|
||||
Ruleset = ruleset;
|
||||
|
||||
// Evaluate the mod string
|
||||
Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray();
|
||||
|
30
osu.Game/Online/API/Requests/GetUserScoresRequest.cs
Normal file
30
osu.Game/Online/API/Requests/GetUserScoresRequest.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// 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.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetUserScoresRequest : APIRequest<List<OnlineScore>>
|
||||
{
|
||||
private readonly long userId;
|
||||
private readonly ScoreType type;
|
||||
private readonly int offset;
|
||||
|
||||
public GetUserScoresRequest(long userId, ScoreType type, int offset = 0)
|
||||
{
|
||||
this.userId = userId;
|
||||
this.type = type;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
protected override string Target => $@"users/{userId}/scores/{type.ToString().ToLower()}?offset={offset}";
|
||||
}
|
||||
|
||||
public enum ScoreType
|
||||
{
|
||||
Best,
|
||||
Firsts,
|
||||
Recent
|
||||
}
|
||||
}
|
32
osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs
Normal file
32
osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs
Normal file
@ -0,0 +1,32 @@
|
||||
// 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.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Direct;
|
||||
using osu.Game.Rulesets;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class SearchBeatmapSetsRequest : APIRequest<IEnumerable<GetBeatmapSetsResponse>>
|
||||
{
|
||||
private readonly string query;
|
||||
private readonly RulesetInfo ruleset;
|
||||
private readonly RankStatus rankStatus;
|
||||
private readonly DirectSortCriteria sortCriteria;
|
||||
private readonly SortDirection direction;
|
||||
private string directionString => direction == SortDirection.Descending ? @"desc" : @"asc";
|
||||
|
||||
public SearchBeatmapSetsRequest(string query, RulesetInfo ruleset, RankStatus rankStatus = RankStatus.Any, DirectSortCriteria sortCriteria = DirectSortCriteria.Ranked, SortDirection direction = SortDirection.Descending)
|
||||
{
|
||||
this.query = System.Uri.EscapeDataString(query);
|
||||
this.ruleset = ruleset;
|
||||
this.rankStatus = rankStatus;
|
||||
this.sortCriteria = sortCriteria;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={(int)rankStatus}&sort={sortCriteria.ToString().ToLower()}_{directionString}";
|
||||
}
|
||||
}
|
@ -188,8 +188,8 @@ namespace osu.Game
|
||||
GetToolbarHeight = () => ToolbarOffset,
|
||||
Depth = -1
|
||||
}, overlayContent.Add);
|
||||
LoadComponentAsync(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -2 }, mainContent.Add);
|
||||
LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -3 }, mainContent.Add);
|
||||
LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add);
|
||||
LoadComponentAsync(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -3 }, mainContent.Add);
|
||||
LoadComponentAsync(musicController = new MusicController
|
||||
{
|
||||
Depth = -4,
|
||||
|
@ -17,7 +17,6 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Graphics.Processing;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Framework.Graphics.Performance;
|
||||
using osu.Game.Database;
|
||||
@ -193,7 +192,7 @@ namespace osu.Game
|
||||
|
||||
GlobalKeyBindingInputManager globalBinding;
|
||||
|
||||
base.Content.Add(new RatioAdjust
|
||||
base.Content.Add(new DrawSizePreservingFillContainer
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
@ -12,9 +11,10 @@ using osu.Framework.Input;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Game.Overlays.Direct;
|
||||
using osu.Framework.Configuration;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
@ -22,73 +22,16 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
private const float transition_duration = 500;
|
||||
|
||||
private readonly Container audioWrapper;
|
||||
private readonly Box bg, progress;
|
||||
private readonly SpriteIcon icon;
|
||||
private readonly LoadingAnimation loadingAnimation;
|
||||
private readonly PlayButton playButton;
|
||||
|
||||
private Track preview;
|
||||
private Track preview => playButton.Preview;
|
||||
private Bindable<bool> playing => playButton.Playing;
|
||||
|
||||
private bool loading
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
loadingAnimation.Show();
|
||||
icon.FadeOut(transition_duration * 5, Easing.OutQuint);
|
||||
}
|
||||
else
|
||||
{
|
||||
loadingAnimation.Hide();
|
||||
icon.FadeIn(transition_duration, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BeatmapSetInfo beatmapSet;
|
||||
public BeatmapSetInfo BeatmapSet
|
||||
{
|
||||
get { return beatmapSet; }
|
||||
set
|
||||
{
|
||||
if (value == beatmapSet) return;
|
||||
beatmapSet = value;
|
||||
|
||||
Playing = false;
|
||||
preview = null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool playing;
|
||||
public bool Playing
|
||||
{
|
||||
get { return playing; }
|
||||
set
|
||||
{
|
||||
if (value == playing) return;
|
||||
playing = value;
|
||||
|
||||
if (preview == null)
|
||||
{
|
||||
loading = true;
|
||||
audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper(BeatmapSet)
|
||||
{
|
||||
OnLoadComplete = d =>
|
||||
{
|
||||
loading = false;
|
||||
|
||||
preview = (d as AudioLoadWrapper)?.Preview;
|
||||
Playing = Playing;
|
||||
updatePlayingState();
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
updatePlayingState();
|
||||
}
|
||||
get { return playButton.BeatmapSet; }
|
||||
set { playButton.BeatmapSet = value; }
|
||||
}
|
||||
|
||||
public PreviewButton()
|
||||
@ -97,7 +40,6 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
audioWrapper = new Container(),
|
||||
bg = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -116,22 +58,16 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
Alpha = 0f,
|
||||
},
|
||||
},
|
||||
icon = new SpriteIcon
|
||||
playButton = new PlayButton
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Icon = FontAwesome.fa_play,
|
||||
Size = new Vector2(18),
|
||||
Shadow = false,
|
||||
},
|
||||
loadingAnimation = new LoadingAnimation
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
};
|
||||
|
||||
Action = () => Playing = !Playing;
|
||||
Action = () => playing.Value = !playing.Value;
|
||||
playing.ValueChanged += newValue => progress.FadeTo(newValue ? 1 : 0, 100);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -144,20 +80,15 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (Playing && preview != null)
|
||||
if (playing.Value && preview != null)
|
||||
{
|
||||
progress.Width = (float)(preview.CurrentTime / preview.Length);
|
||||
if (preview.HasCompleted)
|
||||
{
|
||||
Playing = false;
|
||||
preview = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
Playing = false;
|
||||
playing.Value = false;
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
|
||||
@ -172,47 +103,5 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
bg.FadeColour(Color4.Black.Opacity(0.25f), 100);
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
|
||||
private void updatePlayingState()
|
||||
{
|
||||
if (preview == null) return;
|
||||
|
||||
if (Playing)
|
||||
{
|
||||
icon.Icon = FontAwesome.fa_stop;
|
||||
progress.FadeIn(100);
|
||||
|
||||
preview.Seek(0);
|
||||
preview.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
icon.Icon = FontAwesome.fa_play;
|
||||
progress.FadeOut(100);
|
||||
preview.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private class AudioLoadWrapper : Drawable
|
||||
{
|
||||
private readonly string preview;
|
||||
|
||||
public Track Preview;
|
||||
|
||||
public AudioLoadWrapper(BeatmapSetInfo set)
|
||||
{
|
||||
preview = set.OnlineInfo.Preview;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(preview))
|
||||
{
|
||||
Preview = audio.Track.Get(preview);
|
||||
Preview.Volume.Value = 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
@ -11,7 +12,10 @@ using osu.Framework.Input;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Overlays.BeatmapSet;
|
||||
using osu.Game.Rulesets;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
@ -23,6 +27,9 @@ namespace osu.Game.Overlays
|
||||
private readonly Header header;
|
||||
private readonly Info info;
|
||||
|
||||
private APIAccess api;
|
||||
private RulesetStore rulesets;
|
||||
|
||||
// receive input outside our bounds so we can trigger a close event on ourselves.
|
||||
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true;
|
||||
|
||||
@ -75,6 +82,13 @@ namespace osu.Game.Overlays
|
||||
header.Picker.Beatmap.ValueChanged += b => info.Beatmap = b;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(APIAccess api, RulesetStore rulesets)
|
||||
{
|
||||
this.api = api;
|
||||
this.rulesets = rulesets;
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
base.PopIn();
|
||||
@ -93,6 +107,14 @@ namespace osu.Game.Overlays
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ShowBeatmapSet(int beatmapSetId)
|
||||
{
|
||||
// todo: display the overlay while we are loading here. we need to support setting BeatmapSet to null for this to work.
|
||||
var req = new GetBeatmapSetRequest(beatmapSetId);
|
||||
req.Success += res => ShowBeatmapSet(res.ToBeatmapSet(rulesets));
|
||||
api.Queue(req);
|
||||
}
|
||||
|
||||
public void ShowBeatmapSet(BeatmapSetInfo set)
|
||||
{
|
||||
header.BeatmapSet = info.BeatmapSet = set;
|
||||
|
@ -21,6 +21,11 @@ namespace osu.Game.Overlays.Direct
|
||||
private const float vertical_padding = 5;
|
||||
|
||||
private FillFlowContainer bottomPanel;
|
||||
private PlayButton playButton;
|
||||
private Box progressBar;
|
||||
|
||||
protected override PlayButton PlayButton => playButton;
|
||||
protected override Box PreviewBar => progressBar;
|
||||
|
||||
public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap)
|
||||
{
|
||||
@ -87,6 +92,15 @@ namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
progressBar = new Box
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
BypassAutoSizeAxes = Axes.Both,
|
||||
Size = new Vector2(0, 3),
|
||||
Alpha = 0,
|
||||
Colour = colours.Yellow,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -178,6 +192,12 @@ namespace osu.Game.Overlays.Direct
|
||||
new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0),
|
||||
},
|
||||
},
|
||||
playButton = new PlayButton(SetInfo)
|
||||
{
|
||||
Margin = new MarginPadding { Top = 5, Left = 10 },
|
||||
Size = new Vector2(30),
|
||||
Alpha = 0,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -28,8 +28,14 @@ namespace osu.Game.Overlays.Direct
|
||||
Height = height;
|
||||
}
|
||||
|
||||
private PlayButton playButton;
|
||||
private Box progressBar;
|
||||
|
||||
protected override PlayButton PlayButton => playButton;
|
||||
protected override Box PreviewBar => progressBar;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LocalisationEngine localisation)
|
||||
private void load(LocalisationEngine localisation, OsuColour colours)
|
||||
{
|
||||
Content.CornerRadius = 5;
|
||||
|
||||
@ -48,29 +54,50 @@ namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Direction = FillDirection.Horizontal,
|
||||
LayoutEasing = Easing.OutQuint,
|
||||
LayoutDuration = 120,
|
||||
Spacing = new Vector2(10, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
playButton = new PlayButton(SetInfo)
|
||||
{
|
||||
Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title),
|
||||
TextSize = 18,
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist),
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Size = new Vector2(height / 2),
|
||||
FillMode = FillMode.Fit,
|
||||
Alpha = 0,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = 20,
|
||||
Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding },
|
||||
Children = GetDifficultyIcons(),
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title),
|
||||
TextSize = 18,
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist),
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = 20,
|
||||
Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding },
|
||||
Children = GetDifficultyIcons(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
@ -126,6 +153,16 @@ namespace osu.Game.Overlays.Direct
|
||||
},
|
||||
},
|
||||
},
|
||||
progressBar = new Box
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
BypassAutoSizeAxes = Axes.Y,
|
||||
Size = new Vector2(0, 3),
|
||||
Alpha = 0,
|
||||
Colour = colours.Yellow,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ using osu.Game.Online.API;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Audio.Track;
|
||||
|
||||
namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
@ -39,6 +41,11 @@ namespace osu.Game.Overlays.Direct
|
||||
private NotificationOverlay notifications;
|
||||
private BeatmapSetOverlay beatmapSetOverlay;
|
||||
|
||||
public Track Preview => PlayButton.Preview;
|
||||
public Bindable<bool> PreviewPlaying => PlayButton.Playing;
|
||||
protected abstract PlayButton PlayButton { get; }
|
||||
protected abstract Box PreviewBar { get; }
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
protected DirectPanel(BeatmapSetInfo setInfo)
|
||||
@ -104,10 +111,21 @@ namespace osu.Game.Overlays.Direct
|
||||
attachDownload(downloadRequest);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (PreviewPlaying && Preview != null)
|
||||
{
|
||||
PreviewBar.Width = (float)(Preview.CurrentTime / Preview.Length);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint);
|
||||
content.MoveToY(-4, hover_transition_time, Easing.OutQuint);
|
||||
PlayButton.FadeIn(120, Easing.InOutQuint);
|
||||
|
||||
return base.OnHover(state);
|
||||
}
|
||||
@ -116,6 +134,8 @@ namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint);
|
||||
content.MoveToY(0, hover_transition_time, Easing.OutQuint);
|
||||
if (!PreviewPlaying)
|
||||
PlayButton.FadeOut(120, Easing.InOutQuint);
|
||||
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
@ -123,6 +143,7 @@ namespace osu.Game.Overlays.Direct
|
||||
protected override bool OnClick(InputState state)
|
||||
{
|
||||
ShowInformation();
|
||||
PreviewPlaying.Value = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -183,6 +204,9 @@ namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
base.LoadComplete();
|
||||
this.FadeInFromZero(200, Easing.Out);
|
||||
|
||||
PreviewPlaying.ValueChanged += newValue => PlayButton.FadeTo(newValue || IsHovered ? 1 : 0, 120, Easing.InOutQuint);
|
||||
PreviewPlaying.ValueChanged += newValue => PreviewBar.FadeTo(newValue ? 1 : 0, 120, Easing.InOutQuint);
|
||||
}
|
||||
|
||||
protected List<DifficultyIcon> GetDifficultyIcons()
|
||||
|
185
osu.Game/Overlays/Direct/PlayButton.cs
Normal file
185
osu.Game/Overlays/Direct/PlayButton.cs
Normal file
@ -0,0 +1,185 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
public class PlayButton : Container
|
||||
{
|
||||
public readonly Bindable<bool> Playing = new Bindable<bool>();
|
||||
public Track Preview { get; private set; }
|
||||
|
||||
private BeatmapSetInfo beatmapSet;
|
||||
public BeatmapSetInfo BeatmapSet
|
||||
{
|
||||
get { return beatmapSet; }
|
||||
set
|
||||
{
|
||||
if (value == beatmapSet) return;
|
||||
beatmapSet = value;
|
||||
|
||||
Playing.Value = false;
|
||||
trackLoader = null;
|
||||
Preview = null;
|
||||
}
|
||||
}
|
||||
|
||||
private Color4 hoverColour;
|
||||
private readonly SpriteIcon icon;
|
||||
private readonly LoadingAnimation loadingAnimation;
|
||||
|
||||
private const float transition_duration = 500;
|
||||
|
||||
private bool loading
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
loadingAnimation.Show();
|
||||
icon.FadeOut(transition_duration * 5, Easing.OutQuint);
|
||||
}
|
||||
else
|
||||
{
|
||||
loadingAnimation.Hide();
|
||||
icon.FadeIn(transition_duration, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PlayButton(BeatmapSetInfo setInfo = null)
|
||||
{
|
||||
BeatmapSet = setInfo;
|
||||
AddRange(new Drawable[]
|
||||
{
|
||||
icon = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fit,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Icon = FontAwesome.fa_play,
|
||||
},
|
||||
loadingAnimation = new LoadingAnimation(),
|
||||
});
|
||||
|
||||
Playing.ValueChanged += playing =>
|
||||
{
|
||||
icon.Icon = playing ? FontAwesome.fa_pause : FontAwesome.fa_play;
|
||||
icon.FadeColour(playing || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint);
|
||||
updatePreviewTrack(playing);
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colour)
|
||||
{
|
||||
hoverColour = colour.Yellow;
|
||||
}
|
||||
|
||||
protected override bool OnClick(InputState state)
|
||||
{
|
||||
Playing.Value = !Playing.Value;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
icon.FadeColour(hoverColour, 120, Easing.InOutQuint);
|
||||
return base.OnHover(state);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
if (!Playing.Value)
|
||||
icon.FadeColour(Color4.White, 120, Easing.InOutQuint);
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (Preview?.HasCompleted ?? false)
|
||||
{
|
||||
Playing.Value = false;
|
||||
Preview = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePreviewTrack(bool playing)
|
||||
{
|
||||
if (playing)
|
||||
{
|
||||
if (Preview == null)
|
||||
{
|
||||
beginAudioLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
Preview.Seek(0);
|
||||
Preview.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
Preview?.Stop();
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private TrackLoader trackLoader;
|
||||
|
||||
private void beginAudioLoad()
|
||||
{
|
||||
if (trackLoader != null) return;
|
||||
|
||||
loading = true;
|
||||
|
||||
Add(new AsyncLoadWrapper(trackLoader = new TrackLoader($"https://b.ppy.sh/preview/{BeatmapSet.OnlineBeatmapSetID}.mp3")
|
||||
{
|
||||
OnLoadComplete = d =>
|
||||
{
|
||||
// we may have been replaced by another loader
|
||||
if (trackLoader != d) return;
|
||||
|
||||
Preview = (d as TrackLoader)?.Preview;
|
||||
Playing.TriggerChange();
|
||||
loading = false;
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
private class TrackLoader : Drawable
|
||||
{
|
||||
private readonly string preview;
|
||||
|
||||
public Track Preview;
|
||||
|
||||
public TrackLoader(string preview)
|
||||
{
|
||||
this.preview = preview;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(preview))
|
||||
{
|
||||
Preview = audio.Track.Get(preview);
|
||||
Preview.Volume.Value = 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ namespace osu.Game.Overlays
|
||||
private readonly FillFlowContainer resultCountsContainer;
|
||||
private readonly OsuSpriteText resultCountsText;
|
||||
private FillFlowContainer<DirectPanel> panels;
|
||||
private DirectPanel playing;
|
||||
|
||||
protected override Color4 BackgroundColour => OsuColour.FromHex(@"485e74");
|
||||
protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"465b71");
|
||||
@ -201,6 +202,12 @@ namespace osu.Game.Overlays
|
||||
panels.FadeOut(200);
|
||||
panels.Expire();
|
||||
panels = null;
|
||||
|
||||
if (playing != null)
|
||||
{
|
||||
playing.PreviewPlaying.Value = false;
|
||||
playing = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (BeatmapSets == null) return;
|
||||
@ -227,10 +234,21 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
if (panels != null) ScrollFlow.Remove(panels);
|
||||
ScrollFlow.Add(panels = newPanels);
|
||||
|
||||
foreach (DirectPanel panel in p.Children)
|
||||
panel.PreviewPlaying.ValueChanged += newValue =>
|
||||
{
|
||||
if (newValue)
|
||||
{
|
||||
if (playing != null && playing != panel)
|
||||
playing.PreviewPlaying.Value = false;
|
||||
playing = panel;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private GetBeatmapSetsRequest getSetsRequest;
|
||||
private SearchBeatmapSetsRequest getSetsRequest;
|
||||
|
||||
private readonly Bindable<string> currentQuery = new Bindable<string>();
|
||||
|
||||
@ -251,7 +269,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
if (Header.Tabs.Current.Value == DirectTab.Search && (Filter.Search.Text == string.Empty || currentQuery == string.Empty)) return;
|
||||
|
||||
getSetsRequest = new GetBeatmapSetsRequest(currentQuery.Value ?? string.Empty,
|
||||
getSetsRequest = new SearchBeatmapSetsRequest(currentQuery.Value ?? string.Empty,
|
||||
((FilterControl)Filter).Ruleset.Value,
|
||||
Filter.DisplayStyleControl.Dropdown.Current.Value,
|
||||
Filter.Tabs.Current.Value); //todo: sort direction (?)
|
||||
|
@ -159,7 +159,7 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,7 @@ namespace osu.Game.Overlays.MedalSplash
|
||||
},
|
||||
description = new TextFlowContainer
|
||||
{
|
||||
TextAnchor = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -115,15 +116,16 @@ namespace osu.Game.Overlays.MedalSplash
|
||||
medalSprite.Texture = textures.Get(medal.ImageUrl);
|
||||
medalGlow.Texture = textures.Get(@"MedalSplash/medal-glow");
|
||||
description.Colour = colours.BlueLight;
|
||||
|
||||
unlocked.Position = new Vector2(0f, medalContainer.Size.Y / 2 + 10);
|
||||
infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
updateState();
|
||||
|
||||
unlocked.Position = new Vector2(0f, medalContainer.DrawSize.Y / 2 + 10);
|
||||
infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90);
|
||||
}
|
||||
|
||||
public DisplayState State
|
||||
@ -172,6 +174,7 @@ namespace osu.Game.Overlays.MedalSplash
|
||||
|
||||
this.ScaleTo(scale_when_full, duration, Easing.OutExpo);
|
||||
this.MoveToY(MedalOverlay.DISC_SIZE / 2 - 60, duration, Easing.OutExpo);
|
||||
unlocked.Show();
|
||||
name.FadeInFromZero(duration + 100);
|
||||
description.FadeInFromZero(duration * 2);
|
||||
break;
|
||||
|
@ -161,11 +161,15 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
prevButton = new IconButton
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Action = prev,
|
||||
Icon = FontAwesome.fa_step_backward,
|
||||
},
|
||||
playButton = new IconButton
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(1.4f),
|
||||
IconScale = new Vector2(1.4f),
|
||||
Action = play,
|
||||
@ -173,6 +177,8 @@ namespace osu.Game.Overlays
|
||||
},
|
||||
nextButton = new IconButton
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Action = next,
|
||||
Icon = FontAwesome.fa_step_forward,
|
||||
},
|
||||
|
@ -12,13 +12,14 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Users;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
|
||||
namespace osu.Game.Overlays.Profile
|
||||
{
|
||||
@ -119,15 +120,11 @@ namespace osu.Game.Overlays.Profile
|
||||
}
|
||||
}
|
||||
},
|
||||
new LinkFlowContainer.LinkText
|
||||
new LinkFlowContainer.ProfileLink(user)
|
||||
{
|
||||
Text = user.Username,
|
||||
Url = $@"https://osu.ppy.sh/users/{user.Id}",
|
||||
TextSize = 30,
|
||||
Font = @"Exo2.0-RegularItalic",
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Y = -48
|
||||
Y = -48,
|
||||
},
|
||||
countryFlag = new DrawableFlag(user.Country?.FlagName)
|
||||
{
|
||||
@ -509,34 +506,42 @@ namespace osu.Game.Overlays.Profile
|
||||
|
||||
public class LinkText : OsuSpriteText
|
||||
{
|
||||
public override bool HandleInput => Url != null;
|
||||
private readonly OsuHoverContainer content;
|
||||
|
||||
public string Url;
|
||||
public override bool HandleInput => content.Action != null;
|
||||
|
||||
private Color4 hoverColour;
|
||||
protected override Container<Drawable> Content => content ?? (Container<Drawable>)this;
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
protected override IEnumerable<Drawable> FlowingChildren => Children;
|
||||
|
||||
public string Url
|
||||
{
|
||||
this.FadeColour(hoverColour, 500, Easing.OutQuint);
|
||||
return base.OnHover(state);
|
||||
set
|
||||
{
|
||||
if(value != null)
|
||||
content.Action = () => Process.Start(value);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
public LinkText()
|
||||
{
|
||||
this.FadeColour(Color4.White, 500, Easing.OutQuint);
|
||||
base.OnHoverLost(state);
|
||||
AddInternal(content = new OsuHoverContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnClick(InputState state)
|
||||
{
|
||||
Process.Start(Url);
|
||||
return true;
|
||||
}
|
||||
public class ProfileLink : LinkText, IHasTooltip
|
||||
{
|
||||
public string TooltipText => "View Profile in Browser";
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
public ProfileLink(User user)
|
||||
{
|
||||
hoverColour = colours.Yellow;
|
||||
Text = user.Username;
|
||||
Url = $@"https://osu.ppy.sh/users/{user.Id}";
|
||||
Font = @"Exo2.0-RegularItalic";
|
||||
TextSize = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Users;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Profile
|
||||
@ -18,8 +19,17 @@ namespace osu.Game.Overlays.Profile
|
||||
public abstract string Identifier { get; }
|
||||
|
||||
private readonly FillFlowContainer content;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
public virtual User User
|
||||
{
|
||||
get { return user; }
|
||||
set { user = value; }
|
||||
}
|
||||
|
||||
private User user;
|
||||
|
||||
protected ProfileSection()
|
||||
{
|
||||
Direction = FillDirection.Vertical;
|
||||
|
164
osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs
Normal file
164
osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs
Normal file
@ -0,0 +1,164 @@
|
||||
// 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.Collections.Generic;
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using System.Linq;
|
||||
using osu.Framework.Localisation;
|
||||
using System.Globalization;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using System;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
{
|
||||
public class DrawableScore : Container
|
||||
{
|
||||
private readonly FillFlowContainer<OsuSpriteText> stats;
|
||||
private readonly FillFlowContainer metadata;
|
||||
private readonly ModContainer modContainer;
|
||||
private readonly Score score;
|
||||
private readonly double? weight;
|
||||
|
||||
public DrawableScore(Score score, double? weight = null)
|
||||
{
|
||||
this.score = score;
|
||||
this.weight = weight;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableRank(score.Rank)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 60,
|
||||
FillMode = FillMode.Fit,
|
||||
},
|
||||
stats = new FillFlowContainer<OsuSpriteText>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Direction = FillDirection.Vertical,
|
||||
},
|
||||
metadata = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Left = 70 },
|
||||
Direction = FillDirection.Vertical,
|
||||
Child = new OsuSpriteText
|
||||
{
|
||||
Text = score.Date.LocalDateTime.ToShortDateString(),
|
||||
TextSize = 11,
|
||||
Colour = OsuColour.Gray(0xAA),
|
||||
Depth = -1,
|
||||
},
|
||||
},
|
||||
modContainer = new ModContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Width = 60,
|
||||
Margin = new MarginPadding { Right = 150 }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colour, LocalisationEngine locale, BeatmapSetOverlay beatmapSetOverlay)
|
||||
{
|
||||
stats.Add(new OsuSpriteText
|
||||
{
|
||||
Text = $"{Math.Round(score.PP ?? 0)}pp",
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
TextSize = 18,
|
||||
Font = "Exo2.0-BoldItalic",
|
||||
});
|
||||
|
||||
if (weight.HasValue)
|
||||
{
|
||||
stats.Add(new OsuSpriteText
|
||||
{
|
||||
Text = $"weighted: {Math.Round(score.PP * weight ?? 0)}pp ({weight.Value.ToString("0%", CultureInfo.CurrentCulture)})",
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Colour = colour.GrayA,
|
||||
TextSize = 11,
|
||||
Font = "Exo2.0-RegularItalic",
|
||||
});
|
||||
}
|
||||
|
||||
stats.Add(new OsuSpriteText
|
||||
{
|
||||
Text = "accuracy: " + score.Accuracy.ToString("0.00%"),
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Colour = colour.GrayA,
|
||||
TextSize = 11,
|
||||
Font = "Exo2.0-RegularItalic",
|
||||
});
|
||||
|
||||
metadata.Add(new OsuHoverContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Action = () =>
|
||||
{
|
||||
if (score.Beatmap.OnlineBeatmapSetID.HasValue) beatmapSetOverlay.ShowBeatmapSet(score.Beatmap.OnlineBeatmapSetID.Value);
|
||||
},
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Current = locale.GetUnicodePreference(
|
||||
$"{score.Beatmap.Metadata.TitleUnicode ?? score.Beatmap.Metadata.Title} [{score.Beatmap.Version}] ",
|
||||
$"{score.Beatmap.Metadata.Title ?? score.Beatmap.Metadata.TitleUnicode} [{score.Beatmap.Version}] "
|
||||
),
|
||||
TextSize = 15,
|
||||
Font = "Exo2.0-SemiBoldItalic",
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Current = locale.GetUnicodePreference(score.Beatmap.Metadata.ArtistUnicode, score.Beatmap.Metadata.Artist),
|
||||
TextSize = 12,
|
||||
Padding = new MarginPadding { Top = 3 },
|
||||
Font = "Exo2.0-RegularItalic",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
foreach (Mod mod in score.Mods)
|
||||
modContainer.Add(new ModIcon(mod)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Scale = new Vector2(0.5f),
|
||||
});
|
||||
}
|
||||
|
||||
private class ModContainer : FlowContainer<ModIcon>
|
||||
{
|
||||
protected override IEnumerable<Vector2> ComputeLayoutPositions()
|
||||
{
|
||||
int count = FlowingChildren.Count();
|
||||
for (int i = 0; i < count; i++)
|
||||
yield return new Vector2(DrawWidth * i * (count == 1 ? 0 : 1f / (count - 1)), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,21 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Users;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections
|
||||
{
|
||||
public class RanksSection : ProfileSection
|
||||
@ -8,5 +23,148 @@ namespace osu.Game.Overlays.Profile.Sections
|
||||
public override string Title => "Ranks";
|
||||
|
||||
public override string Identifier => "top_ranks";
|
||||
|
||||
private readonly ScoreContainer best, first;
|
||||
|
||||
public RanksSection()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
best = new ScoreContainer(ScoreType.Best, "Best Performance", true),
|
||||
first = new ScoreContainer(ScoreType.Firsts, "First Place Ranks"),
|
||||
};
|
||||
}
|
||||
|
||||
public override User User
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.User;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
base.User = value;
|
||||
best.User = value;
|
||||
first.User = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class ScoreContainer : FillFlowContainer
|
||||
{
|
||||
private readonly FillFlowContainer<DrawableScore> scoreContainer;
|
||||
private readonly OsuSpriteText missing;
|
||||
private readonly OsuHoverContainer showMoreButton;
|
||||
private readonly LoadingAnimation showMoreLoading;
|
||||
|
||||
private readonly ScoreType type;
|
||||
private int visiblePages;
|
||||
private User user;
|
||||
private readonly bool includeWeigth;
|
||||
|
||||
private RulesetStore rulesets;
|
||||
private APIAccess api;
|
||||
|
||||
public User User
|
||||
{
|
||||
set
|
||||
{
|
||||
user = value;
|
||||
visiblePages = 0;
|
||||
scoreContainer.Clear();
|
||||
showMoreButton.Hide();
|
||||
missing.Show();
|
||||
showMore();
|
||||
}
|
||||
}
|
||||
|
||||
public ScoreContainer(ScoreType type, string header, bool includeWeigth = false)
|
||||
{
|
||||
this.type = type;
|
||||
this.includeWeigth = includeWeigth;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Direction = FillDirection.Vertical;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
TextSize = 15,
|
||||
Text = header,
|
||||
Font = "Exo2.0-RegularItalic",
|
||||
Margin = new MarginPadding { Top = 10, Bottom = 10 },
|
||||
},
|
||||
scoreContainer = new FillFlowContainer<DrawableScore>
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Direction = FillDirection.Vertical,
|
||||
},
|
||||
showMoreButton = new OsuHoverContainer
|
||||
{
|
||||
Alpha = 0,
|
||||
Action = showMore,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Child = new OsuSpriteText
|
||||
{
|
||||
TextSize = 14,
|
||||
Text = "show more",
|
||||
}
|
||||
},
|
||||
showMoreLoading = new LoadingAnimation
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Size = new Vector2(14),
|
||||
},
|
||||
missing = new OsuSpriteText
|
||||
{
|
||||
TextSize = 14,
|
||||
Text = "No awesome performance records yet. :(",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(APIAccess api, RulesetStore rulesets)
|
||||
{
|
||||
this.api = api;
|
||||
this.rulesets = rulesets;
|
||||
}
|
||||
|
||||
private void showMore()
|
||||
{
|
||||
var req = new GetUserScoresRequest(user.Id, type, visiblePages++ * 5);
|
||||
|
||||
showMoreLoading.Show();
|
||||
showMoreButton.Hide();
|
||||
|
||||
req.Success += scores =>
|
||||
{
|
||||
foreach (var s in scores)
|
||||
s.ApplyRuleset(rulesets.GetRuleset(s.OnlineRulesetID));
|
||||
|
||||
showMoreButton.FadeTo(scores.Count == 5 ? 1 : 0);
|
||||
showMoreLoading.Hide();
|
||||
|
||||
if (scores.Any())
|
||||
{
|
||||
missing.Hide();
|
||||
foreach (OnlineScore score in scores)
|
||||
scoreContainer.Add(new DrawableScore(score, includeWeigth ? Math.Pow(0.95, scoreContainer.Count) : -1)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 60,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Schedule(() => { api.Queue(req); });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,12 +92,12 @@ namespace osu.Game.Overlays
|
||||
sections = new ProfileSection[]
|
||||
{
|
||||
new AboutSection(),
|
||||
new RecentSection(),
|
||||
//new RecentSection(),
|
||||
new RanksSection(),
|
||||
new MedalsSection(),
|
||||
new HistoricalSection(),
|
||||
new BeatmapsSection(),
|
||||
new KudosuSection()
|
||||
//new MedalsSection(),
|
||||
//new HistoricalSection(),
|
||||
//new BeatmapsSection(),
|
||||
//new KudosuSection()
|
||||
};
|
||||
tabs = new ProfileTabControl
|
||||
{
|
||||
@ -175,6 +175,8 @@ namespace osu.Game.Overlays
|
||||
var sec = sections.FirstOrDefault(s => s.Identifier == id);
|
||||
if (sec != null)
|
||||
{
|
||||
sec.User = user;
|
||||
|
||||
sectionsContainer.Add(sec);
|
||||
tabs.AddItem(sec);
|
||||
}
|
||||
|
@ -200,4 +200,4 @@ namespace osu.Game.Rulesets.Objects
|
||||
return interpolateVertices(indexOfDistance(d), d) + Offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
public double Health { get; set; } = 1;
|
||||
|
||||
public double? PP { get; set; }
|
||||
|
||||
public int MaxCombo { get; set; }
|
||||
|
||||
public int Combo { get; set; }
|
||||
|
@ -6,13 +6,14 @@ using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
public class ModIcon : Container
|
||||
public class ModIcon : Container, IHasTooltip
|
||||
{
|
||||
private readonly SpriteIcon modIcon;
|
||||
private readonly SpriteIcon background;
|
||||
@ -27,12 +28,16 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
private readonly ModType type;
|
||||
|
||||
public string TooltipText { get; }
|
||||
|
||||
public ModIcon(Mod mod)
|
||||
{
|
||||
if (mod == null) throw new ArgumentNullException(nameof(mod));
|
||||
|
||||
type = mod.Type;
|
||||
|
||||
TooltipText = mod.Name;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
background = new SpriteIcon
|
||||
|
@ -6,6 +6,7 @@ using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Screens.Compose
|
||||
{
|
||||
@ -13,6 +14,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
||||
{
|
||||
public Compose()
|
||||
{
|
||||
ScrollableTimeline timeline;
|
||||
Children = new[]
|
||||
{
|
||||
new Container
|
||||
@ -31,11 +33,22 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
||||
{
|
||||
Name = "Content",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Horizontal = 17, Vertical = 10 }
|
||||
Padding = new MarginPadding { Horizontal = 17, Vertical = 10 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Right = 115 },
|
||||
Child = timeline = new ScrollableTimeline { RelativeSizeAxes = Axes.Both }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
timeline.Beatmap.BindTo(Beatmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Audio;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
{
|
||||
public class BeatmapWaveformGraph : CompositeDrawable
|
||||
{
|
||||
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly WaveformGraph graph;
|
||||
|
||||
public BeatmapWaveformGraph()
|
||||
{
|
||||
InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both };
|
||||
Beatmap.ValueChanged += b => graph.Waveform = b.Waveform;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="WaveformGraph.Resolution"/>.
|
||||
/// </summary>
|
||||
public float Resolution
|
||||
{
|
||||
get { return graph.Resolution; }
|
||||
set { graph.Resolution = value; }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
// 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.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
{
|
||||
public class ScrollableTimeline : CompositeDrawable
|
||||
{
|
||||
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly ScrollingTimelineContainer timelineContainer;
|
||||
|
||||
public ScrollableTimeline()
|
||||
{
|
||||
Masking = true;
|
||||
CornerRadius = 5;
|
||||
|
||||
OsuCheckbox hitObjectsCheckbox;
|
||||
OsuCheckbox hitSoundsCheckbox;
|
||||
OsuCheckbox waveformCheckbox;
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.FromHex("111")
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.FromHex("222")
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Width = 160,
|
||||
Padding = new MarginPadding { Horizontal = 15 },
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 4),
|
||||
Children = new[]
|
||||
{
|
||||
hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" },
|
||||
hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" },
|
||||
waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.FromHex("333")
|
||||
},
|
||||
new Container<TimelineButton>
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Masking = true,
|
||||
Children = new[]
|
||||
{
|
||||
new TimelineButton
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Height = 0.5f,
|
||||
Icon = FontAwesome.fa_search_plus,
|
||||
Action = () => timelineContainer.Zoom++
|
||||
},
|
||||
new TimelineButton
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Height = 0.5f,
|
||||
Icon = FontAwesome.fa_search_minus,
|
||||
Action = () => timelineContainer.Zoom--
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Y }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
hitObjectsCheckbox.Current.Value = true;
|
||||
hitSoundsCheckbox.Current.Value = true;
|
||||
waveformCheckbox.Current.Value = true;
|
||||
|
||||
timelineContainer.Beatmap.BindTo(Beatmap);
|
||||
timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
// 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 osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
{
|
||||
internal class ScrollingTimelineContainer : ScrollContainer
|
||||
{
|
||||
public readonly Bindable<bool> HitObjectsVisible = new Bindable<bool>();
|
||||
public readonly Bindable<bool> HitSoundsVisible = new Bindable<bool>();
|
||||
public readonly Bindable<bool> WaveformVisible = new Bindable<bool>();
|
||||
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly BeatmapWaveformGraph waveform;
|
||||
|
||||
public ScrollingTimelineContainer()
|
||||
: base(Direction.Horizontal)
|
||||
{
|
||||
Masking = true;
|
||||
|
||||
Add(waveform = new BeatmapWaveformGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.FromHex("222"),
|
||||
Depth = float.MaxValue
|
||||
});
|
||||
|
||||
Content.AutoSizeAxes = Axes.None;
|
||||
Content.RelativeSizeAxes = Axes.Both;
|
||||
|
||||
waveform.Beatmap.BindTo(Beatmap);
|
||||
WaveformVisible.ValueChanged += waveformVisibilityChanged;
|
||||
|
||||
Zoom = 10;
|
||||
}
|
||||
|
||||
private float minZoom = 1;
|
||||
/// <summary>
|
||||
/// The minimum zoom level allowed.
|
||||
/// </summary>
|
||||
public float MinZoom
|
||||
{
|
||||
get { return minZoom; }
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(value));
|
||||
if (minZoom == value)
|
||||
return;
|
||||
minZoom = value;
|
||||
|
||||
// Update the zoom level
|
||||
Zoom = Zoom;
|
||||
}
|
||||
}
|
||||
|
||||
private float maxZoom = 30;
|
||||
/// <summary>
|
||||
/// The maximum zoom level allowed.
|
||||
/// </summary>
|
||||
public float MaxZoom
|
||||
{
|
||||
get { return maxZoom; }
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(value));
|
||||
if (maxZoom == value)
|
||||
return;
|
||||
maxZoom = value;
|
||||
|
||||
// Update the zoom level
|
||||
Zoom = Zoom;
|
||||
}
|
||||
}
|
||||
|
||||
private float zoom = 1;
|
||||
/// <summary>
|
||||
/// The current zoom level.
|
||||
/// </summary>
|
||||
public float Zoom
|
||||
{
|
||||
get { return zoom; }
|
||||
set
|
||||
{
|
||||
value = MathHelper.Clamp(value, MinZoom, MaxZoom);
|
||||
if (zoom == value)
|
||||
return;
|
||||
zoom = value;
|
||||
|
||||
// Make the zoom target default to the center of the graph if it hasn't been set
|
||||
if (relativeContentZoomTarget == null)
|
||||
relativeContentZoomTarget = ToSpaceOfOtherDrawable(DrawSize / 2, Content).X / Content.DrawSize.X;
|
||||
if (localZoomTarget == null)
|
||||
localZoomTarget = DrawSize.X / 2;
|
||||
|
||||
Content.ResizeWidthTo(Zoom);
|
||||
|
||||
// Update the scroll position to focus on the zoom target
|
||||
float scrollPos = Content.DrawSize.X * relativeContentZoomTarget.Value - localZoomTarget.Value;
|
||||
ScrollTo(scrollPos, false);
|
||||
|
||||
relativeContentZoomTarget = null;
|
||||
localZoomTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Zoom target as a relative position in the <see cref="Content"/> space.
|
||||
/// </summary>
|
||||
private float? relativeContentZoomTarget;
|
||||
|
||||
/// <summary>
|
||||
/// Zoom target as a position in our local space.
|
||||
/// </summary>
|
||||
private float? localZoomTarget;
|
||||
|
||||
protected override bool OnWheel(InputState state)
|
||||
{
|
||||
if (!state.Keyboard.ControlPressed)
|
||||
return base.OnWheel(state);
|
||||
|
||||
relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X;
|
||||
localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X;
|
||||
|
||||
Zoom += state.Mouse.WheelDelta;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
// 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.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
{
|
||||
public class TimelineButton : CompositeDrawable
|
||||
{
|
||||
public Action Action;
|
||||
public readonly BindableBool Enabled = new BindableBool(true);
|
||||
|
||||
public FontAwesome Icon
|
||||
{
|
||||
get { return button.Icon; }
|
||||
set { button.Icon = value; }
|
||||
}
|
||||
|
||||
private readonly IconButton button;
|
||||
|
||||
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()
|
||||
};
|
||||
|
||||
button.Enabled.BindTo(Enabled);
|
||||
Width = button.ButtonSize.X;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
button.ButtonSize = new Vector2(button.ButtonSize.X, DrawHeight);
|
||||
}
|
||||
}
|
||||
}
|
46
osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs
Normal file
46
osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs
Normal file
@ -0,0 +1,46 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseEditorComposeTimeline : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) };
|
||||
|
||||
private readonly ScrollableTimeline timeline;
|
||||
|
||||
public TestCaseEditorComposeTimeline()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new MusicController
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
State = Visibility.Visible
|
||||
},
|
||||
timeline = new ScrollableTimeline
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(1000, 100)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase osuGame)
|
||||
{
|
||||
timeline.Beatmap.BindTo(osuGame.Beatmap);
|
||||
}
|
||||
}
|
||||
}
|
113
osu.Game/Tests/Visual/TestCaseIconButton.cs
Normal file
113
osu.Game/Tests/Visual/TestCaseIconButton.cs
Normal file
@ -0,0 +1,113 @@
|
||||
// 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.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseIconButton : OsuTestCase
|
||||
{
|
||||
public override string Description => "Various display modes of icon buttons";
|
||||
|
||||
public TestCaseIconButton()
|
||||
{
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Spacing = new Vector2(10, 10),
|
||||
Children = new[]
|
||||
{
|
||||
new NamedIconButton("No change", new IconButton()),
|
||||
new NamedIconButton("Background colours", new IconButton
|
||||
{
|
||||
FlashColour = Color4.DarkGreen,
|
||||
HoverColour = Color4.Green,
|
||||
}),
|
||||
new NamedIconButton("Full-width", new IconButton { ButtonSize = new Vector2(200, 30) }),
|
||||
new NamedIconButton("Unchanging size", new IconButton(), false),
|
||||
new NamedIconButton("Icon colours", new IconButton
|
||||
{
|
||||
IconColour = Color4.Green,
|
||||
IconHoverColour = Color4.Red
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class NamedIconButton : Container
|
||||
{
|
||||
public NamedIconButton(string name, IconButton button, bool allowSizeChange = true)
|
||||
{
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Width = 200;
|
||||
|
||||
Container iconContainer;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.5f,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = name
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.1f,
|
||||
},
|
||||
iconContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Child = button
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (allowSizeChange)
|
||||
iconContainer.AutoSizeAxes = Axes.Both;
|
||||
else
|
||||
{
|
||||
iconContainer.RelativeSizeAxes = Axes.X;
|
||||
iconContainer.Height = 30;
|
||||
}
|
||||
|
||||
button.Anchor = Anchor.Centre;
|
||||
button.Origin = Anchor.Centre;
|
||||
button.Icon = FontAwesome.fa_osu_osu_o;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.MedalSplash;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
@ -10,6 +13,12 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public override string Description => @"medal get!";
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(MedalOverlay),
|
||||
typeof(DrawableMedal),
|
||||
};
|
||||
|
||||
public TestCaseMedalOverlay()
|
||||
{
|
||||
AddStep(@"display", () =>
|
||||
|
47
osu.Game/Tests/Visual/TestCaseUserRanks.cs
Normal file
47
osu.Game/Tests/Visual/TestCaseUserRanks.cs
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Overlays.Profile.Sections;
|
||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||
using osu.Game.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseUserRanks : OsuTestCase
|
||||
{
|
||||
public override string Description => "showing your latest achievements";
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(DrawableScore), typeof(RanksSection) };
|
||||
|
||||
public TestCaseUserRanks()
|
||||
{
|
||||
RanksSection ranks;
|
||||
|
||||
Add(new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.Gray(0.2f)
|
||||
},
|
||||
new ScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = ranks = new RanksSection(),
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
AddStep("Show cookiezi", () => ranks.User = new User { Id = 124493 });
|
||||
}
|
||||
}
|
||||
}
|
88
osu.Game/Tests/Visual/TestCaseWaveform.cs
Normal file
88
osu.Game/Tests/Visual/TestCaseWaveform.cs
Normal file
@ -0,0 +1,88 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
internal class TestCaseWaveform : OsuTestCase
|
||||
{
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public TestCaseWaveform()
|
||||
{
|
||||
FillFlowContainer flow;
|
||||
Child = flow = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new MusicController
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Y = 100,
|
||||
State = Visibility.Visible
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 1; i <= 16; i *= 2)
|
||||
{
|
||||
var newDisplay = new BeatmapWaveformGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Resolution = 1f / i
|
||||
};
|
||||
|
||||
newDisplay.Beatmap.BindTo(beatmapBacking);
|
||||
|
||||
flow.Add(new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 100,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
newDisplay,
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.75f
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = $"Resolution: {1f / i:0.00}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap);
|
||||
}
|
||||
}
|
@ -57,7 +57,6 @@
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
@ -77,7 +76,6 @@
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
@ -103,7 +101,6 @@
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<LangVersion>6</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<StartArguments>--tests</StartArguments>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
@ -326,6 +323,9 @@
|
||||
<Compile Include="Beatmaps\Drawables\BeatmapPanel.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\BeatmapSetCover.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\BeatmapSetHeader.cs" />
|
||||
<Compile Include="Online\API\Requests\GetBeatmapSetRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\GetBeatmapSetsResponse.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\Timeline\BeatmapWaveformGraph.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\DifficultyColouredContainer.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\DifficultyIcon.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\Panel.cs" />
|
||||
@ -334,6 +334,8 @@
|
||||
<Compile Include="Beatmaps\Formats\OsuLegacyDecoder.cs" />
|
||||
<Compile Include="Beatmaps\IO\ArchiveReader.cs" />
|
||||
<Compile Include="Beatmaps\IO\LegacyFilesystemReader.cs" />
|
||||
<Compile Include="Online\API\Requests\GetUserScoresRequest.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\Timeline\TimelineButton.cs" />
|
||||
<Compile Include="Screens\Play\BreaksOverlay\ArrowsOverlay.cs" />
|
||||
<Compile Include="Screens\Play\BreaksOverlay\BlurredIcon.cs" />
|
||||
<Compile Include="Screens\Play\BreaksOverlay\BreakOverlay.cs" />
|
||||
@ -362,6 +364,7 @@
|
||||
<Compile Include="Graphics\Containers\ConstrainedIconContainer.cs" />
|
||||
<Compile Include="Graphics\Containers\OsuClickableContainer.cs" />
|
||||
<Compile Include="Graphics\Containers\OsuFocusedOverlayContainer.cs" />
|
||||
<Compile Include="Graphics\Containers\OsuHoverContainer.cs" />
|
||||
<Compile Include="Graphics\Containers\OsuScrollContainer.cs" />
|
||||
<Compile Include="Graphics\Containers\OsuTextFlowContainer.cs" />
|
||||
<Compile Include="Graphics\Containers\ParallaxContainer.cs" />
|
||||
@ -372,7 +375,6 @@
|
||||
<Compile Include="Graphics\Cursor\OsuTooltipContainer.cs" />
|
||||
<Compile Include="Graphics\IHasAccentColour.cs" />
|
||||
<Compile Include="Graphics\OsuColour.cs" />
|
||||
<Compile Include="Graphics\Processing\RatioAdjust.cs" />
|
||||
<Compile Include="Graphics\SpriteIcon.cs" />
|
||||
<Compile Include="Graphics\Sprites\OsuSpriteText.cs" />
|
||||
<Compile Include="Graphics\UserInterface\BackButton.cs" />
|
||||
@ -435,7 +437,7 @@
|
||||
<Compile Include="Online\API\OAuthToken.cs" />
|
||||
<Compile Include="Online\API\Requests\DownloadBeatmapSetRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\GetBeatmapDetailsRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\GetBeatmapSetsRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\SearchBeatmapSetsRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\GetMessagesRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\GetScoresRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\GetUserRequest.cs" />
|
||||
@ -460,6 +462,7 @@
|
||||
<Compile Include="Overlays\Chat\ChannelSelectionOverlay.cs" />
|
||||
<Compile Include="Overlays\Chat\ChatLine.cs" />
|
||||
<Compile Include="Overlays\Chat\ChatTabControl.cs" />
|
||||
<Compile Include="Overlays\Direct\PlayButton.cs" />
|
||||
<Compile Include="Overlays\Chat\DrawableChannel.cs" />
|
||||
<Compile Include="Overlays\DialogOverlay.cs" />
|
||||
<Compile Include="Overlays\Dialog\PopupDialog.cs" />
|
||||
@ -504,6 +507,7 @@
|
||||
<Compile Include="Overlays\Notifications\ProgressNotification.cs" />
|
||||
<Compile Include="Overlays\Notifications\SimpleNotification.cs" />
|
||||
<Compile Include="Overlays\OnScreenDisplay.cs" />
|
||||
<Compile Include="Overlays\Profile\Sections\Ranks\DrawableScore.cs" />
|
||||
<Compile Include="Overlays\Profile\ProfileHeader.cs" />
|
||||
<Compile Include="Overlays\Profile\ProfileSection.cs" />
|
||||
<Compile Include="Overlays\Profile\RankChart.cs" />
|
||||
@ -694,6 +698,8 @@
|
||||
<Compile Include="Screens\Edit\Screens\Design\Design.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\EditorScreen.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\Compose.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\Timeline\ScrollableTimeline.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\Timeline\ScrollingTimelineContainer.cs" />
|
||||
<Compile Include="Screens\Loader.cs" />
|
||||
<Compile Include="Screens\Menu\Button.cs" />
|
||||
<Compile Include="Screens\Menu\ButtonSystem.cs" />
|
||||
@ -820,10 +826,12 @@
|
||||
<Compile Include="Tests\Visual\TestCaseDrawableRoom.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseDrawings.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseEditor.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseEditorComposeTimeline.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseEditorMenuBar.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseEditorSummaryTimeline.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseGamefield.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseGraph.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseIconButton.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseKeyConfiguration.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseKeyCounter.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseLeaderboard.cs" />
|
||||
@ -852,6 +860,8 @@
|
||||
<Compile Include="Tests\Visual\TestCaseTwoLayerButton.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseUserPanel.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseUserProfile.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseUserRanks.cs" />
|
||||
<Compile Include="Tests\Visual\TestCaseWaveform.cs" />
|
||||
<Compile Include="Users\Avatar.cs" />
|
||||
<Compile Include="Users\Country.cs" />
|
||||
<Compile Include="Users\Medal.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user