mirror of
https://github.com/osukey/osukey.git
synced 2025-05-30 01:47:30 +09:00
Merge branch 'master' into channel-selector-tab-item
This commit is contained in:
commit
f6f1ea42ee
@ -1 +1 @@
|
|||||||
Subproject commit c6f030d6f1ab65a48de9ff1d0c424acb686e0149
|
Subproject commit 8baad1b9484b9f35724e2f965c18cfe710907d80
|
199
osu.Desktop.VisualTests/Tests/TestCaseDirect.cs
Normal file
199
osu.Desktop.VisualTests/Tests/TestCaseDirect.cs
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
// 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.Framework.Allocation;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
|
||||||
|
namespace osu.Desktop.VisualTests.Tests
|
||||||
|
{
|
||||||
|
public class TestCaseDirect : TestCase
|
||||||
|
{
|
||||||
|
public override string Description => @"osu!direct overlay";
|
||||||
|
|
||||||
|
private DirectOverlay direct;
|
||||||
|
private RulesetDatabase rulesets;
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
base.Reset();
|
||||||
|
|
||||||
|
Add(direct = new DirectOverlay());
|
||||||
|
newBeatmaps();
|
||||||
|
|
||||||
|
AddStep(@"toggle", direct.ToggleVisibility);
|
||||||
|
AddStep(@"result counts", () => direct.ResultAmounts = new DirectOverlay.ResultCounts(1, 4, 13));
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(RulesetDatabase rulesets)
|
||||||
|
{
|
||||||
|
this.rulesets = rulesets;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void newBeatmaps()
|
||||||
|
{
|
||||||
|
var ruleset = rulesets.GetRuleset(0);
|
||||||
|
|
||||||
|
direct.BeatmapSets = new[]
|
||||||
|
{
|
||||||
|
new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = @"OrVid",
|
||||||
|
Artist = @"An",
|
||||||
|
Author = @"RLC",
|
||||||
|
Source = @"",
|
||||||
|
},
|
||||||
|
Beatmaps = new List<BeatmapInfo>
|
||||||
|
{
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 5.35f,
|
||||||
|
Metadata = new BeatmapMetadata(),
|
||||||
|
OnlineInfo = new BeatmapOnlineInfo
|
||||||
|
{
|
||||||
|
Covers = new[] { @"https://assets.ppy.sh//beatmaps/578332/covers/cover.jpg?1494591390" },
|
||||||
|
Preview = @"https://b.ppy.sh/preview/578332.mp3",
|
||||||
|
PlayCount = 97,
|
||||||
|
FavouriteCount = 72,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = @"tiny lamp",
|
||||||
|
Artist = @"fhana",
|
||||||
|
Author = @"Sotarks",
|
||||||
|
Source = @"ぎんぎつね",
|
||||||
|
},
|
||||||
|
Beatmaps = new List<BeatmapInfo>
|
||||||
|
{
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 5.81f,
|
||||||
|
Metadata = new BeatmapMetadata(),
|
||||||
|
OnlineInfo = new BeatmapOnlineInfo
|
||||||
|
{
|
||||||
|
Covers = new[] { @"https://assets.ppy.sh//beatmaps/599627/covers/cover.jpg?1494539318" },
|
||||||
|
Preview = @"https//b.ppy.sh/preview/599627.mp3",
|
||||||
|
PlayCount = 3082,
|
||||||
|
FavouriteCount = 14,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = @"At Gwanghwamun",
|
||||||
|
Artist = @"KYUHYUN",
|
||||||
|
Author = @"Cerulean Veyron",
|
||||||
|
Source = @"",
|
||||||
|
},
|
||||||
|
Beatmaps = new List<BeatmapInfo>
|
||||||
|
{
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 0.9f,
|
||||||
|
Metadata = new BeatmapMetadata(),
|
||||||
|
OnlineInfo = new BeatmapOnlineInfo
|
||||||
|
{
|
||||||
|
Covers = new[] { @"https://assets.ppy.sh//beatmaps/513268/covers/cover.jpg?1494502863" },
|
||||||
|
Preview = @"https//b.ppy.sh/preview/513268.mp3",
|
||||||
|
PlayCount = 2762,
|
||||||
|
FavouriteCount = 15,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 1.1f,
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 2.02f,
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 3.49f,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = @"RHAPSODY OF BLUE SKY",
|
||||||
|
Artist = @"fhana",
|
||||||
|
Author = @"[Kamiya]",
|
||||||
|
Source = @"小林さんちのメイドラゴン",
|
||||||
|
},
|
||||||
|
Beatmaps = new List<BeatmapInfo>
|
||||||
|
{
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 1.26f,
|
||||||
|
Metadata = new BeatmapMetadata(),
|
||||||
|
OnlineInfo = new BeatmapOnlineInfo
|
||||||
|
{
|
||||||
|
Covers = new[] { @"https://assets.ppy.sh//beatmaps/586841/covers/cover.jpg?1494052741" },
|
||||||
|
Preview = @"https//b.ppy.sh/preview/586841.mp3",
|
||||||
|
PlayCount = 62317,
|
||||||
|
FavouriteCount = 161,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 2.01f,
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 2.87f,
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 3.76f,
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 3.93f,
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 4.37f,
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 5.13f,
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
StarDifficulty = 5.42f,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
74
osu.Desktop.VisualTests/Tests/TestCaseDrawableRoom.cs
Normal file
74
osu.Desktop.VisualTests/Tests/TestCaseDrawableRoom.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// 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.Containers;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Screens.Multiplayer;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osu.Game.Database;
|
||||||
|
|
||||||
|
namespace osu.Desktop.VisualTests.Tests
|
||||||
|
{
|
||||||
|
internal class TestCaseDrawableRoom : TestCase
|
||||||
|
{
|
||||||
|
public override string Description => @"Select your favourite room";
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
base.Reset();
|
||||||
|
|
||||||
|
DrawableRoom first;
|
||||||
|
DrawableRoom second;
|
||||||
|
Add(new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Width = 500f,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
first = new DrawableRoom(new Room()),
|
||||||
|
second = new DrawableRoom(new Room()),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
first.Room.Name.Value = @"Great Room Right Here";
|
||||||
|
first.Room.Host.Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" }};
|
||||||
|
first.Room.Status.Value = new RoomStatusOpen();
|
||||||
|
first.Room.Beatmap.Value = new BeatmapMetadata { Title = @"Seiryu", Artist = @"Critical Crystal" };
|
||||||
|
|
||||||
|
second.Room.Name.Value = @"Relax It's The Weekend";
|
||||||
|
second.Room.Host.Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" }};
|
||||||
|
second.Room.Status.Value = new RoomStatusPlaying();
|
||||||
|
second.Room.Beatmap.Value = new BeatmapMetadata { Title = @"ZAQ", Artist = @"Serendipity" };
|
||||||
|
|
||||||
|
AddStep(@"change state", () =>
|
||||||
|
{
|
||||||
|
first.Room.Status.Value = new RoomStatusPlaying();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep(@"change name", () =>
|
||||||
|
{
|
||||||
|
first.Room.Name.Value = @"I Changed Name";
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep(@"change host", () =>
|
||||||
|
{
|
||||||
|
first.Room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } };
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep(@"change beatmap", () =>
|
||||||
|
{
|
||||||
|
first.Room.Beatmap.Value = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep(@"change state", () =>
|
||||||
|
{
|
||||||
|
first.Room.Status.Value = new RoomStatusOpen();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
osu.Desktop.VisualTests/Tests/TestCaseUserPanel.cs
Normal file
57
osu.Desktop.VisualTests/Tests/TestCaseUserPanel.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// 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.Testing;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace osu.Desktop.VisualTests.Tests
|
||||||
|
{
|
||||||
|
internal class TestCaseUserPanel : TestCase
|
||||||
|
{
|
||||||
|
public override string Description => @"Panels for displaying a user's status";
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
base.Reset();
|
||||||
|
|
||||||
|
UserPanel flyte;
|
||||||
|
UserPanel peppy;
|
||||||
|
Add(new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Spacing = new Vector2(10f),
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
flyte = new UserPanel(new User
|
||||||
|
{
|
||||||
|
Username = @"flyte",
|
||||||
|
Id = 3103765,
|
||||||
|
Country = new Country { FlagName = @"JP" },
|
||||||
|
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/3103765/5b012e13611d5761caa7e24fecb3d3a16e1cf48fc2a3032cfd43dd444af83d82.jpeg"
|
||||||
|
}) { Width = 300 },
|
||||||
|
peppy = new UserPanel(new User
|
||||||
|
{
|
||||||
|
Username = @"peppy",
|
||||||
|
Id = 2,
|
||||||
|
Country = new Country { FlagName = @"AU" },
|
||||||
|
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/2/08cad88747c235a64fca5f1b770e100f120827ded1ffe3b66bfcd19c940afa65.jpeg"
|
||||||
|
}) { Width = 300 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
flyte.Status.Value = new UserStatusOnline();
|
||||||
|
peppy.Status.Value = new UserStatusSoloGame();
|
||||||
|
|
||||||
|
AddStep(@"spectating", () => { flyte.Status.Value = new UserStatusSpectating(); });
|
||||||
|
AddStep(@"multiplaying", () => { flyte.Status.Value = new UserStatusMultiplayerGame(); });
|
||||||
|
AddStep(@"modding", () => { flyte.Status.Value = new UserStatusModding(); });
|
||||||
|
AddStep(@"offline", () => { flyte.Status.Value = new UserStatusOffline(); });
|
||||||
|
AddStep(@"null status", () => { flyte.Status.Value = null; });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -220,6 +220,9 @@
|
|||||||
<Compile Include="Tests\TestCaseLeaderboard.cs" />
|
<Compile Include="Tests\TestCaseLeaderboard.cs" />
|
||||||
<Compile Include="Beatmaps\TestWorkingBeatmap.cs" />
|
<Compile Include="Beatmaps\TestWorkingBeatmap.cs" />
|
||||||
<Compile Include="Tests\TestCaseBeatmapDetailArea.cs" />
|
<Compile Include="Tests\TestCaseBeatmapDetailArea.cs" />
|
||||||
|
<Compile Include="Tests\TestCaseDrawableRoom.cs" />
|
||||||
|
<Compile Include="Tests\TestCaseUserPanel.cs" />
|
||||||
|
<Compile Include="Tests\TestCaseDirect.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
|
@ -24,6 +24,9 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
base.ApplyDefaults(controlPointInfo, difficulty);
|
base.ApplyDefaults(controlPointInfo, difficulty);
|
||||||
|
|
||||||
SpinsRequired = (int)(Duration / 1000 * BeatmapDifficulty.DifficultyRange(difficulty.OverallDifficulty, 3, 5, 7.5));
|
SpinsRequired = (int)(Duration / 1000 * BeatmapDifficulty.DifficultyRange(difficulty.OverallDifficulty, 3, 5, 7.5));
|
||||||
|
|
||||||
|
// spinning doesn't match 1:1 with stable, so let's fudge them easier for the time being.
|
||||||
|
SpinsRequired = (int)(SpinsRequired * 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
||||||
{
|
{
|
||||||
@ -22,6 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
public const float SYMBOL_SIZE = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER * 0.45f;
|
public const float SYMBOL_SIZE = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER * 0.45f;
|
||||||
public const float SYMBOL_BORDER = 8;
|
public const float SYMBOL_BORDER = 8;
|
||||||
public const float SYMBOL_INNER_SIZE = SYMBOL_SIZE - 2 * SYMBOL_BORDER;
|
public const float SYMBOL_INNER_SIZE = SYMBOL_SIZE - 2 * SYMBOL_BORDER;
|
||||||
|
private const double pre_beat_transition_time = 80;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The colour of the inner circle and outer glows.
|
/// The colour of the inner circle and outer glows.
|
||||||
@ -63,6 +66,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
public CirclePiece(bool isStrong = false)
|
public CirclePiece(bool isStrong = false)
|
||||||
{
|
{
|
||||||
|
EarlyActivationMilliseconds = pre_beat_transition_time;
|
||||||
|
|
||||||
AddInternal(new Drawable[]
|
AddInternal(new Drawable[]
|
||||||
{
|
{
|
||||||
background = new CircularContainer
|
background = new CircularContainer
|
||||||
@ -139,14 +144,31 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
Content.Width = 1 / Content.Scale.X;
|
Content.Width = 1 / Content.Scale.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const float edge_alpha_kiai = 0.5f;
|
||||||
|
|
||||||
private void resetEdgeEffects()
|
private void resetEdgeEffects()
|
||||||
{
|
{
|
||||||
background.EdgeEffect = new EdgeEffect
|
background.EdgeEffect = new EdgeEffect
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
Colour = AccentColour,
|
Colour = AccentColour.Opacity(KiaiMode ? edge_alpha_kiai : 1f),
|
||||||
Radius = KiaiMode ? 50 : 8
|
Radius = KiaiMode ? 32 : 8
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||||
|
{
|
||||||
|
if (!effectPoint.KiaiMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (beatIndex % (int)timingPoint.TimeSignature != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double duration = timingPoint.BeatLength * 2;
|
||||||
|
|
||||||
|
background.FadeEdgeEffectTo(1, pre_beat_transition_time, EasingTypes.OutQuint);
|
||||||
|
using (background.BeginDelayedSequence(pre_beat_transition_time))
|
||||||
|
background.FadeEdgeEffectTo(edge_alpha_kiai, duration, EasingTypes.OutQuint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +1,14 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
||||||
{
|
{
|
||||||
public class TaikoPiece : Container, IHasAccentColour
|
public class TaikoPiece : BeatSyncedContainer, IHasAccentColour
|
||||||
{
|
{
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -17,10 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
public virtual Color4 AccentColour
|
public virtual Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return accentColour; }
|
get { return accentColour; }
|
||||||
set
|
set { accentColour = value; }
|
||||||
{
|
|
||||||
accentColour = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool kiaiMode;
|
private bool kiaiMode;
|
||||||
|
@ -13,12 +13,12 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Diameter of a circle relative to the size of the <see cref="TaikoPlayfield"/>.
|
/// Diameter of a circle relative to the size of the <see cref="TaikoPlayfield"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const float PLAYFIELD_RELATIVE_DIAMETER = 0.5f;
|
public const float PLAYFIELD_RELATIVE_DIAMETER = 0.45f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scale multiplier for a strong circle.
|
/// Scale multiplier for a strong circle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const float STRONG_CIRCLE_DIAMETER_SCALE = 1.5f;
|
public const float STRONG_CIRCLE_DIAMETER_SCALE = 1.4f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default circle diameter.
|
/// Default circle diameter.
|
||||||
|
@ -18,22 +18,23 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class HitExplosion : CircularContainer
|
internal class HitExplosion : CircularContainer
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The judgement this hit explosion visualises.
|
|
||||||
/// </summary>
|
|
||||||
public readonly TaikoJudgement Judgement;
|
public readonly TaikoJudgement Judgement;
|
||||||
|
|
||||||
private readonly Box innerFill;
|
private readonly Box innerFill;
|
||||||
|
|
||||||
public HitExplosion(TaikoJudgement judgement)
|
private readonly bool isRim;
|
||||||
{
|
|
||||||
Judgement = judgement;
|
|
||||||
|
|
||||||
Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER);
|
public HitExplosion(TaikoJudgement judgement, bool isRim)
|
||||||
|
{
|
||||||
|
this.isRim = isRim;
|
||||||
|
|
||||||
|
Judgement = judgement;
|
||||||
|
|
||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
Size = new Vector2(TaikoPlayfield.HIT_TARGET_OFFSET + TaikoHitObject.DEFAULT_CIRCLE_DIAMETER);
|
||||||
|
|
||||||
RelativePositionAxes = Axes.Both;
|
RelativePositionAxes = Axes.Both;
|
||||||
|
|
||||||
BorderColour = Color4.White;
|
BorderColour = Color4.White;
|
||||||
@ -54,22 +55,14 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
switch (Judgement.TaikoResult)
|
innerFill.Colour = isRim ? colours.BlueDarker : colours.PinkDarker;
|
||||||
{
|
|
||||||
case TaikoHitResult.Good:
|
|
||||||
innerFill.Colour = colours.Green;
|
|
||||||
break;
|
|
||||||
case TaikoHitResult.Great:
|
|
||||||
innerFill.Colour = colours.Blue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
ScaleTo(5f, 1000, EasingTypes.OutQuint);
|
ScaleTo(3f, 1000, EasingTypes.OutQuint);
|
||||||
FadeOut(500);
|
FadeOut(500);
|
||||||
|
|
||||||
Expire();
|
Expire();
|
||||||
@ -80,7 +73,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void VisualiseSecondHit()
|
public void VisualiseSecondHit()
|
||||||
{
|
{
|
||||||
ResizeTo(Size * TaikoHitObject.STRONG_CIRCLE_DIAMETER_SCALE, 50);
|
ResizeTo(new Vector2(TaikoPlayfield.HIT_TARGET_OFFSET + TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER), 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
68
osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs
Normal file
68
osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using OpenTK;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
|
{
|
||||||
|
public class KiaiHitExplosion : CircularContainer
|
||||||
|
{
|
||||||
|
public readonly TaikoJudgement Judgement;
|
||||||
|
|
||||||
|
private readonly bool isRim;
|
||||||
|
|
||||||
|
public KiaiHitExplosion(TaikoJudgement judgement, bool isRim)
|
||||||
|
{
|
||||||
|
this.isRim = isRim;
|
||||||
|
|
||||||
|
Judgement = judgement;
|
||||||
|
|
||||||
|
Anchor = Anchor.Centre;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Y;
|
||||||
|
Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER, 1);
|
||||||
|
|
||||||
|
Masking = true;
|
||||||
|
Alpha = 0.25f;
|
||||||
|
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0,
|
||||||
|
AlwaysPresent = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
EdgeEffect = new EdgeEffect
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Glow,
|
||||||
|
Colour = isRim ? colours.BlueDarker : colours.PinkDarker,
|
||||||
|
Radius = 60,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
ScaleTo(new Vector2(1, 3f), 500, EasingTypes.OutQuint);
|
||||||
|
FadeOut(250);
|
||||||
|
|
||||||
|
Expire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,12 +24,12 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default play field height.
|
/// The default play field height.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const float DEFAULT_PLAYFIELD_HEIGHT = 168f;
|
public const float DEFAULT_PLAYFIELD_HEIGHT = 178f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The offset from <see cref="left_area_size"/> which the center of the hit target lies at.
|
/// The offset from <see cref="left_area_size"/> which the center of the hit target lies at.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const float hit_target_offset = TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER / 2f + 40;
|
public const float HIT_TARGET_OFFSET = TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER / 2f + 40;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The size of the left area of the playfield. This area contains the input drum.
|
/// The size of the left area of the playfield. This area contains the input drum.
|
||||||
@ -39,15 +39,18 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
protected override Container<Drawable> Content => hitObjectContainer;
|
protected override Container<Drawable> Content => hitObjectContainer;
|
||||||
|
|
||||||
private readonly Container<HitExplosion> hitExplosionContainer;
|
private readonly Container<HitExplosion> hitExplosionContainer;
|
||||||
|
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
|
||||||
private readonly Container<DrawableBarLine> barLineContainer;
|
private readonly Container<DrawableBarLine> barLineContainer;
|
||||||
private readonly Container<DrawableTaikoJudgement> judgementContainer;
|
private readonly Container<DrawableTaikoJudgement> judgementContainer;
|
||||||
|
|
||||||
private readonly Container hitObjectContainer;
|
private readonly Container hitObjectContainer;
|
||||||
private readonly Container topLevelHitContainer;
|
private readonly Container topLevelHitContainer;
|
||||||
private readonly Container leftBackgroundContainer;
|
|
||||||
private readonly Container rightBackgroundContainer;
|
private readonly Container overlayBackgroundContainer;
|
||||||
private readonly Box leftBackground;
|
private readonly Container backgroundContainer;
|
||||||
private readonly Box rightBackground;
|
|
||||||
|
private readonly Box overlayBackground;
|
||||||
|
private readonly Box background;
|
||||||
|
|
||||||
public TaikoPlayfield()
|
public TaikoPlayfield()
|
||||||
{
|
{
|
||||||
@ -59,7 +62,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
Height = DEFAULT_PLAYFIELD_HEIGHT,
|
Height = DEFAULT_PLAYFIELD_HEIGHT,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
rightBackgroundContainer = new Container
|
backgroundContainer = new Container
|
||||||
{
|
{
|
||||||
Name = "Transparent playfield background",
|
Name = "Transparent playfield background",
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
@ -73,7 +76,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
},
|
},
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
rightBackground = new Box
|
background = new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Alpha = 0.6f
|
Alpha = 0.6f
|
||||||
@ -82,24 +85,23 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
Name = "Transparent playfield elements",
|
Name = "Right area",
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding { Left = left_area_size },
|
Margin = new MarginPadding { Left = left_area_size },
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
Name = "Hit target container",
|
Name = "Masked elements",
|
||||||
X = hit_target_offset,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
|
||||||
|
Masking = true,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
hitExplosionContainer = new Container<HitExplosion>
|
hitExplosionContainer = new Container<HitExplosion>
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
BlendingMode = BlendingMode.Additive
|
BlendingMode = BlendingMode.Additive,
|
||||||
},
|
},
|
||||||
barLineContainer = new Container<DrawableBarLine>
|
barLineContainer = new Container<DrawableBarLine>
|
||||||
{
|
{
|
||||||
@ -114,23 +116,32 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
judgementContainer = new Container<DrawableTaikoJudgement>
|
}
|
||||||
{
|
},
|
||||||
RelativeSizeAxes = Axes.Y,
|
kiaiExplosionContainer = new Container<KiaiHitExplosion>
|
||||||
BlendingMode = BlendingMode.Additive
|
{
|
||||||
},
|
Name = "Kiai hit explosions",
|
||||||
},
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
|
||||||
|
BlendingMode = BlendingMode.Additive
|
||||||
|
},
|
||||||
|
judgementContainer = new Container<DrawableTaikoJudgement>
|
||||||
|
{
|
||||||
|
Name = "Judgements",
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
|
||||||
|
BlendingMode = BlendingMode.Additive
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
leftBackgroundContainer = new Container
|
overlayBackgroundContainer = new Container
|
||||||
{
|
{
|
||||||
Name = "Left overlay",
|
Name = "Left overlay",
|
||||||
Size = new Vector2(left_area_size, DEFAULT_PLAYFIELD_HEIGHT),
|
Size = new Vector2(left_area_size, DEFAULT_PLAYFIELD_HEIGHT),
|
||||||
BorderThickness = 1,
|
BorderThickness = 1,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
leftBackground = new Box
|
overlayBackground = new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
@ -164,11 +175,11 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
leftBackgroundContainer.BorderColour = colours.Gray0;
|
overlayBackgroundContainer.BorderColour = colours.Gray0;
|
||||||
leftBackground.Colour = colours.Gray1;
|
overlayBackground.Colour = colours.Gray1;
|
||||||
|
|
||||||
rightBackgroundContainer.BorderColour = colours.Gray1;
|
backgroundContainer.BorderColour = colours.Gray1;
|
||||||
rightBackground.Colour = colours.Gray0;
|
background.Colour = colours.Gray0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Add(DrawableHitObject<TaikoHitObject, TaikoJudgement> h)
|
public override void Add(DrawableHitObject<TaikoHitObject, TaikoJudgement> h)
|
||||||
@ -204,6 +215,8 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
if (!wasHit)
|
if (!wasHit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool isRim = judgedObject.HitObject is RimHit;
|
||||||
|
|
||||||
if (!secondHit)
|
if (!secondHit)
|
||||||
{
|
{
|
||||||
if (judgedObject.X >= -0.05f && !(judgedObject is DrawableSwell))
|
if (judgedObject.X >= -0.05f && !(judgedObject is DrawableSwell))
|
||||||
@ -212,7 +225,11 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
||||||
}
|
}
|
||||||
|
|
||||||
hitExplosionContainer.Add(new HitExplosion(judgedObject.Judgement));
|
hitExplosionContainer.Add(new HitExplosion(judgedObject.Judgement, isRim));
|
||||||
|
|
||||||
|
if (judgedObject.HitObject.Kiai)
|
||||||
|
kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject.Judgement, isRim));
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hitExplosionContainer.Children.FirstOrDefault(e => e.Judgement == judgedObject.Judgement)?.VisualiseSecondHit();
|
hitExplosionContainer.Children.FirstOrDefault(e => e.Judgement == judgedObject.Judgement)?.VisualiseSecondHit();
|
||||||
@ -221,7 +238,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is a very special type of container. It serves a similar purpose to <see cref="FillMode.Fit"/>, however unlike <see cref="FillMode.Fit"/>,
|
/// This is a very special type of container. It serves a similar purpose to <see cref="FillMode.Fit"/>, however unlike <see cref="FillMode.Fit"/>,
|
||||||
/// this will only adjust the scale relative to the height of its parent and will maintain the original width relative to its parent.
|
/// this will only adjust the scale relative to the height of its parent and will maintain the original width relative to its parent.
|
||||||
///
|
///
|
||||||
/// <para>
|
/// <para>
|
||||||
/// By adjusting the scale relative to the height of its parent, the aspect ratio of this container's children is maintained, however this is undesirable
|
/// By adjusting the scale relative to the height of its parent, the aspect ratio of this container's children is maintained, however this is undesirable
|
||||||
/// in the case where the hit object container should not have its width adjusted by scale. To counteract this, another container is nested inside this
|
/// in the case where the hit object container should not have its width adjusted by scale. To counteract this, another container is nested inside this
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
<Compile Include="Scoring\TaikoScoreProcessor.cs" />
|
<Compile Include="Scoring\TaikoScoreProcessor.cs" />
|
||||||
<Compile Include="UI\HitTarget.cs" />
|
<Compile Include="UI\HitTarget.cs" />
|
||||||
<Compile Include="UI\InputDrum.cs" />
|
<Compile Include="UI\InputDrum.cs" />
|
||||||
|
<Compile Include="UI\KiaiHitExplosion.cs" />
|
||||||
<Compile Include="UI\DrawableTaikoJudgement.cs" />
|
<Compile Include="UI\DrawableTaikoJudgement.cs" />
|
||||||
<Compile Include="UI\HitExplosion.cs" />
|
<Compile Include="UI\HitExplosion.cs" />
|
||||||
<Compile Include="UI\TaikoHitRenderer.cs" />
|
<Compile Include="UI\TaikoHitRenderer.cs" />
|
||||||
|
@ -55,7 +55,7 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">The time to find the timing control point at.</param>
|
/// <param name="time">The time to find the timing control point at.</param>
|
||||||
/// <returns>The timing control point.</returns>
|
/// <returns>The timing control point.</returns>
|
||||||
public TimingControlPoint TimingPointAt(double time) => binarySearch(TimingPoints, time);
|
public TimingControlPoint TimingPointAt(double time) => binarySearch(TimingPoints, time, TimingPoints.FirstOrDefault());
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the maximum BPM represented by any timing control point.
|
/// Finds the maximum BPM represented by any timing control point.
|
||||||
@ -75,14 +75,21 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
public double BPMMode =>
|
public double BPMMode =>
|
||||||
60000 / (TimingPoints.GroupBy(c => c.BeatLength).OrderByDescending(grp => grp.Count()).FirstOrDefault()?.FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
|
60000 / (TimingPoints.GroupBy(c => c.BeatLength).OrderByDescending(grp => grp.Count()).FirstOrDefault()?.FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
|
||||||
|
|
||||||
private T binarySearch<T>(SortedList<T> list, double time)
|
/// <summary>
|
||||||
|
/// Binary searches one of the control point lists to find the active control point at <paramref name="time"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="list">The list to search.</param>
|
||||||
|
/// <param name="time">The time to find the control point at.</param>
|
||||||
|
/// <param name="prePoint">The control point to use when <paramref name="time"/> is before any control points. If null, a new control point will be constructed.</param>
|
||||||
|
/// <returns>The active control point at <paramref name="time"/>.</returns>
|
||||||
|
private T binarySearch<T>(SortedList<T> list, double time, T prePoint = null)
|
||||||
where T : ControlPoint, new()
|
where T : ControlPoint, new()
|
||||||
{
|
{
|
||||||
if (list.Count == 0)
|
if (list.Count == 0)
|
||||||
return new T();
|
return new T();
|
||||||
|
|
||||||
if (time < list[0].Time)
|
if (time < list[0].Time)
|
||||||
return new T();
|
return prePoint ?? new T();
|
||||||
|
|
||||||
int index = list.BinarySearch(new T() { Time = time });
|
int index = list.BinarySearch(new T() { Time = time });
|
||||||
|
|
||||||
@ -92,8 +99,8 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
|
|
||||||
index = ~index;
|
index = ~index;
|
||||||
|
|
||||||
if (index == list.Count)
|
// BinarySearch will return the index of the first element _greater_ than the search
|
||||||
return list[list.Count - 1];
|
// This is the inactive point - the active point is the one before it (index - 1)
|
||||||
return list[index - 1];
|
return list[index - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ using OpenTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Beatmaps.Drawables
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
{
|
{
|
||||||
internal class DifficultyColouredContainer : Container, IHasAccentColour
|
public class DifficultyColouredContainer : Container, IHasAccentColour
|
||||||
{
|
{
|
||||||
public Color4 AccentColour { get; set; }
|
public Color4 AccentColour { get; set; }
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ using OpenTK.Graphics;
|
|||||||
namespace osu.Game.Beatmaps.Drawables
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
{
|
{
|
||||||
|
|
||||||
internal class DifficultyIcon : DifficultyColouredContainer
|
public class DifficultyIcon : DifficultyColouredContainer
|
||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
|
|
||||||
|
@ -43,6 +43,9 @@ namespace osu.Game.Database
|
|||||||
[Ignore]
|
[Ignore]
|
||||||
public BeatmapMetrics Metrics { get; set; }
|
public BeatmapMetrics Metrics { get; set; }
|
||||||
|
|
||||||
|
[Ignore]
|
||||||
|
public BeatmapOnlineInfo OnlineInfo { get; set; }
|
||||||
|
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
|
||||||
[JsonProperty("file_md5")]
|
[JsonProperty("file_md5")]
|
||||||
|
38
osu.Game/Database/BeatmapOnlineInfo.cs
Normal file
38
osu.Game/Database/BeatmapOnlineInfo.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace osu.Game.Database
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Beatmap info retrieved for previewing locally without having the beatmap downloaded.
|
||||||
|
/// </summary>
|
||||||
|
public class BeatmapOnlineInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The different sizes of cover art for this beatmap: cover, cover@2x, card, card@2x, list, list@2x.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(@"covers")]
|
||||||
|
public IEnumerable<string> Covers { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A small sample clip of this beatmap's song.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(@"previewUrl")]
|
||||||
|
public string Preview { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of plays this beatmap has.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(@"play_count")]
|
||||||
|
public int PlayCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of people who have favourited this map.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(@"favourite_count")]
|
||||||
|
public int FavouriteCount { get; set; }
|
||||||
|
}
|
||||||
|
}
|
37
osu.Game/Database/OnlineWorkingBeatmap.cs
Normal file
37
osu.Game/Database/OnlineWorkingBeatmap.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
|
||||||
|
namespace osu.Game.Database
|
||||||
|
{
|
||||||
|
internal class OnlineWorkingBeatmap : WorkingBeatmap
|
||||||
|
{
|
||||||
|
private readonly TextureStore textures;
|
||||||
|
private readonly TrackManager tracks;
|
||||||
|
|
||||||
|
public OnlineWorkingBeatmap(BeatmapInfo beatmapInfo, TextureStore textures, TrackManager tracks) : base(beatmapInfo)
|
||||||
|
{
|
||||||
|
this.textures = textures;
|
||||||
|
this.tracks = tracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Beatmap GetBeatmap()
|
||||||
|
{
|
||||||
|
return new Beatmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Texture GetBackground()
|
||||||
|
{
|
||||||
|
return textures.Get(BeatmapInfo.OnlineInfo.Covers.FirstOrDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Track GetTrack()
|
||||||
|
{
|
||||||
|
return tracks.Get(BeatmapInfo.OnlineInfo.Preview);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
osu.Game/Database/RankStatus.cs
Normal file
23
osu.Game/Database/RankStatus.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// 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.ComponentModel;
|
||||||
|
|
||||||
|
namespace osu.Game.Database
|
||||||
|
{
|
||||||
|
public enum RankStatus
|
||||||
|
{
|
||||||
|
Any = 7,
|
||||||
|
[Description("Ranked & Approved")]
|
||||||
|
RankedApproved = 0,
|
||||||
|
Approved = 1,
|
||||||
|
Loved = 8,
|
||||||
|
Favourites = 2,
|
||||||
|
[Description("Mod Requests")]
|
||||||
|
ModRequests = 3,
|
||||||
|
Pending = 4,
|
||||||
|
Graveyard = 5,
|
||||||
|
[Description("My Maps")]
|
||||||
|
MyMaps = 6,
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,29 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using System;
|
using System;
|
||||||
|
using osu.Framework.Graphics.OpenGL;
|
||||||
|
using osu.Framework.Graphics.Shaders;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using OpenTK.Graphics.ES30;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Framework.Graphics.Primitives;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Graphics.Batches;
|
||||||
|
using osu.Framework.Lists;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.Backgrounds
|
namespace osu.Game.Graphics.Backgrounds
|
||||||
{
|
{
|
||||||
public class Triangles : Container<Triangle>
|
public class Triangles : Drawable
|
||||||
{
|
{
|
||||||
|
private const float triangle_size = 100;
|
||||||
|
|
||||||
public override bool HandleInput => false;
|
public override bool HandleInput => false;
|
||||||
|
|
||||||
public Color4 ColourLight = Color4.White;
|
public Color4 ColourLight = Color4.White;
|
||||||
@ -44,6 +53,33 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HideAlphaDiscrepancies = true;
|
public bool HideAlphaDiscrepancies = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The relative velocity of the triangles. Default is 1.
|
||||||
|
/// </summary>
|
||||||
|
public float Velocity = 1;
|
||||||
|
|
||||||
|
private readonly SortedList<TriangleParticle> parts = new SortedList<TriangleParticle>(Comparer<TriangleParticle>.Default);
|
||||||
|
|
||||||
|
private Shader shader;
|
||||||
|
private readonly Texture texture;
|
||||||
|
|
||||||
|
public Triangles()
|
||||||
|
{
|
||||||
|
texture = Texture.WhitePixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(ShaderManager shaders)
|
||||||
|
{
|
||||||
|
shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
addTriangles(true);
|
||||||
|
}
|
||||||
|
|
||||||
public float TriangleScale
|
public float TriangleScale
|
||||||
{
|
{
|
||||||
get { return triangleScale; }
|
get { return triangleScale; }
|
||||||
@ -52,42 +88,71 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
float change = value / triangleScale;
|
float change = value / triangleScale;
|
||||||
triangleScale = value;
|
triangleScale = value;
|
||||||
|
|
||||||
if (change != 1)
|
for (int i = 0; i < parts.Count; i++)
|
||||||
Children.ForEach(t => t.Scale *= change);
|
{
|
||||||
|
TriangleParticle newParticle = parts[i];
|
||||||
|
newParticle.Scale *= change;
|
||||||
|
parts[i] = newParticle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
addTriangles(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int aimTriangleCount => (int)(DrawWidth * DrawHeight * 0.002f / (triangleScale * triangleScale) * SpawnRatio);
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
float adjustedAlpha = HideAlphaDiscrepancies ?
|
Invalidate(Invalidation.DrawNode, shallPropagate: false);
|
||||||
// Cubically scale alpha to make it drop off more sharply.
|
|
||||||
(float)Math.Pow(DrawInfo.Colour.AverageColour.Linear.A, 3) :
|
|
||||||
1;
|
|
||||||
|
|
||||||
foreach (var t in Children)
|
for (int i = 0; i < parts.Count; i++)
|
||||||
{
|
{
|
||||||
t.Alpha = adjustedAlpha;
|
TriangleParticle newParticle = parts[i];
|
||||||
t.Position -= new Vector2(0, (float)(t.Scale.X * (50 / DrawHeight) * (Time.Elapsed / 950)) / triangleScale);
|
|
||||||
if (ExpireOffScreenTriangles && t.DrawPosition.Y + t.DrawSize.Y * t.Scale.Y < 0)
|
float adjustedAlpha = HideAlphaDiscrepancies ?
|
||||||
t.Expire();
|
// Cubically scale alpha to make it drop off more sharply.
|
||||||
|
(float)Math.Pow(DrawInfo.Colour.AverageColour.Linear.A, 3) :
|
||||||
|
1;
|
||||||
|
|
||||||
|
|
||||||
|
newParticle.Position += new Vector2(0, -(parts[i].Scale * (50 / DrawHeight)) / triangleScale * Velocity) * ((float)Time.Elapsed / 950);
|
||||||
|
newParticle.Colour.A = adjustedAlpha;
|
||||||
|
|
||||||
|
parts[i] = newParticle;
|
||||||
|
|
||||||
|
if (!CreateNewTriangles)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float bottomPos = parts[i].Position.Y + triangle_size * parts[i].Scale * 0.866f / DrawHeight;
|
||||||
|
|
||||||
|
if (bottomPos < 0)
|
||||||
|
parts.RemoveAt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CreateNewTriangles)
|
addTriangles(false);
|
||||||
addTriangles(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Triangle CreateTriangle()
|
private void addTriangles(bool randomY)
|
||||||
|
{
|
||||||
|
int aimTriangleCount = (int)(DrawWidth * DrawHeight * 0.002f / (triangleScale * triangleScale) * SpawnRatio);
|
||||||
|
|
||||||
|
for (int i = 0; i < aimTriangleCount - parts.Count; i++)
|
||||||
|
parts.Add(createTriangle(randomY));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TriangleParticle createTriangle(bool randomY)
|
||||||
|
{
|
||||||
|
TriangleParticle particle = CreateTriangle();
|
||||||
|
|
||||||
|
particle.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() : 1);
|
||||||
|
particle.Colour = CreateTriangleShade();
|
||||||
|
|
||||||
|
return particle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a triangle particle with a random scale.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The triangle particle.</returns>
|
||||||
|
protected virtual TriangleParticle CreateTriangle()
|
||||||
{
|
{
|
||||||
const float std_dev = 0.16f;
|
const float std_dev = 0.16f;
|
||||||
const float mean = 0.5f;
|
const float mean = 0.5f;
|
||||||
@ -97,32 +162,100 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
float randStdNormal = (float)(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2)); //random normal(0,1)
|
float randStdNormal = (float)(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2)); //random normal(0,1)
|
||||||
var scale = Math.Max(triangleScale * (mean + std_dev * randStdNormal), 0.1f); //random normal(mean,stdDev^2)
|
var scale = Math.Max(triangleScale * (mean + std_dev * randStdNormal), 0.1f); //random normal(mean,stdDev^2)
|
||||||
|
|
||||||
const float size = 100;
|
return new TriangleParticle { Scale = scale };
|
||||||
|
|
||||||
return new EquilateralTriangle
|
|
||||||
{
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
RelativePositionAxes = Axes.Both,
|
|
||||||
Size = new Vector2(size),
|
|
||||||
Scale = new Vector2(scale),
|
|
||||||
EdgeSmoothness = new Vector2(1),
|
|
||||||
Colour = GetTriangleShade(),
|
|
||||||
Depth = scale,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Color4 GetTriangleShade() => Interpolation.ValueAt(RNG.NextSingle(), ColourDark, ColourLight, 0, 1);
|
/// <summary>
|
||||||
|
/// Creates a shade of colour for the triangles.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The colour.</returns>
|
||||||
|
protected virtual Color4 CreateTriangleShade() => Interpolation.ValueAt(RNG.NextSingle(), ColourDark, ColourLight, 0, 1);
|
||||||
|
|
||||||
private void addTriangles(bool randomY)
|
protected override DrawNode CreateDrawNode() => new TrianglesDrawNode();
|
||||||
|
|
||||||
|
private readonly TrianglesDrawNodeSharedData sharedData = new TrianglesDrawNodeSharedData();
|
||||||
|
protected override void ApplyDrawNode(DrawNode node)
|
||||||
{
|
{
|
||||||
int addCount = aimTriangleCount - Children.Count();
|
base.ApplyDrawNode(node);
|
||||||
for (int i = 0; i < addCount; i++)
|
|
||||||
|
var trianglesNode = (TrianglesDrawNode)node;
|
||||||
|
|
||||||
|
trianglesNode.Shader = shader;
|
||||||
|
trianglesNode.Texture = texture;
|
||||||
|
trianglesNode.Size = DrawSize;
|
||||||
|
trianglesNode.Shared = sharedData;
|
||||||
|
|
||||||
|
trianglesNode.Parts.Clear();
|
||||||
|
trianglesNode.Parts.AddRange(parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TrianglesDrawNodeSharedData
|
||||||
|
{
|
||||||
|
public readonly LinearBatch<TexturedVertex2D> VertexBatch = new LinearBatch<TexturedVertex2D>(100 * 3, 10, PrimitiveType.Triangles);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TrianglesDrawNode : DrawNode
|
||||||
|
{
|
||||||
|
public Shader Shader;
|
||||||
|
public Texture Texture;
|
||||||
|
|
||||||
|
public TrianglesDrawNodeSharedData Shared;
|
||||||
|
|
||||||
|
public readonly List<TriangleParticle> Parts = new List<TriangleParticle>();
|
||||||
|
public Vector2 Size;
|
||||||
|
|
||||||
|
public override void Draw(Action<TexturedVertex2D> vertexAction)
|
||||||
{
|
{
|
||||||
var sprite = CreateTriangle();
|
base.Draw(vertexAction);
|
||||||
float triangleHeight = sprite.DrawHeight / DrawHeight;
|
|
||||||
sprite.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() * (1 + triangleHeight) - triangleHeight : 1);
|
Shader.Bind();
|
||||||
Add(sprite);
|
Texture.TextureGL.Bind();
|
||||||
|
|
||||||
|
foreach (TriangleParticle particle in Parts)
|
||||||
|
{
|
||||||
|
var offset = new Vector2(particle.Scale * 0.5f, particle.Scale * 0.866f);
|
||||||
|
|
||||||
|
var triangle = new Triangle(
|
||||||
|
particle.Position * Size * DrawInfo.Matrix,
|
||||||
|
(particle.Position * Size + offset * triangle_size) * DrawInfo.Matrix,
|
||||||
|
(particle.Position * Size + new Vector2(-offset.X, offset.Y) * triangle_size) * DrawInfo.Matrix
|
||||||
|
);
|
||||||
|
|
||||||
|
ColourInfo colourInfo = DrawInfo.Colour;
|
||||||
|
colourInfo.ApplyChild(particle.Colour);
|
||||||
|
|
||||||
|
Texture.DrawTriangle(triangle, colourInfo, null, Shared.VertexBatch.Add);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader.Unbind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected struct TriangleParticle : IComparable<TriangleParticle>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The position of the top vertex of the triangle.
|
||||||
|
/// </summary>
|
||||||
|
public Vector2 Position;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The colour of the triangle.
|
||||||
|
/// </summary>
|
||||||
|
public Color4 Colour;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The scale of the triangle.
|
||||||
|
/// </summary>
|
||||||
|
public float Scale;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compares two <see cref="TriangleParticle"/>s. This is a reverse comparer because when the
|
||||||
|
/// triangles are added to the particles list, they should be drawn from largest to smallest
|
||||||
|
/// such that the smaller triangles appear on top.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="other"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int CompareTo(TriangleParticle other) => other.Scale.CompareTo(Scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,59 +2,65 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Beatmaps.Timing;
|
|
||||||
|
|
||||||
namespace osu.Game.Graphics.Containers
|
namespace osu.Game.Graphics.Containers
|
||||||
{
|
{
|
||||||
public class BeatSyncedContainer : Container
|
public class BeatSyncedContainer : Container
|
||||||
{
|
{
|
||||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
protected readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||||
|
|
||||||
private int lastBeat;
|
private int lastBeat;
|
||||||
private TimingControlPoint lastTimingPoint;
|
private TimingControlPoint lastTimingPoint;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of time before a beat we should fire <see cref="OnNewBeat(int, TimingControlPoint, EffectControlPoint, TrackAmplitudes)"/>.
|
||||||
|
/// This allows for adding easing to animations that may be synchronised to the beat.
|
||||||
|
/// </summary>
|
||||||
|
protected double EarlyActivationMilliseconds;
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
if (beatmap.Value?.Track == null)
|
if (Beatmap.Value?.Track == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double currentTrackTime = beatmap.Value.Track.CurrentTime;
|
double currentTrackTime = Beatmap.Value.Track.CurrentTime + EarlyActivationMilliseconds;
|
||||||
|
|
||||||
TimingControlPoint timingPoint = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(currentTrackTime);
|
TimingControlPoint timingPoint = Beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(currentTrackTime);
|
||||||
EffectControlPoint effectPoint = beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(currentTrackTime);
|
EffectControlPoint effectPoint = Beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(currentTrackTime);
|
||||||
|
|
||||||
if (timingPoint.BeatLength == 0)
|
if (timingPoint.BeatLength == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int beat = (int)((currentTrackTime - timingPoint.Time) / timingPoint.BeatLength);
|
int beatIndex = (int)((currentTrackTime - timingPoint.Time) / timingPoint.BeatLength);
|
||||||
|
|
||||||
// The beats before the start of the first control point are off by 1, this should do the trick
|
// The beats before the start of the first control point are off by 1, this should do the trick
|
||||||
if (currentTrackTime < timingPoint.Time)
|
if (currentTrackTime < timingPoint.Time)
|
||||||
beat--;
|
beatIndex--;
|
||||||
|
|
||||||
if (timingPoint == lastTimingPoint && beat == lastBeat)
|
if (timingPoint == lastTimingPoint && beatIndex == lastBeat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double offsetFromBeat = (timingPoint.Time - currentTrackTime) % timingPoint.BeatLength;
|
double offsetFromBeat = (timingPoint.Time - currentTrackTime) % timingPoint.BeatLength;
|
||||||
|
|
||||||
using (BeginDelayedSequence(offsetFromBeat, true))
|
using (BeginDelayedSequence(offsetFromBeat, true))
|
||||||
OnNewBeat(beat, timingPoint.BeatLength, timingPoint.TimeSignature, effectPoint.KiaiMode);
|
OnNewBeat(beatIndex, timingPoint, effectPoint, Beatmap.Value.Track.CurrentAmplitudes);
|
||||||
|
|
||||||
lastBeat = beat;
|
lastBeat = beatIndex;
|
||||||
lastTimingPoint = timingPoint;
|
lastTimingPoint = timingPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase game)
|
private void load(OsuGameBase game)
|
||||||
{
|
{
|
||||||
beatmap.BindTo(game.Beatmap);
|
Beatmap.BindTo(game.Beatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnNewBeat(int newBeat, double beatLength, TimeSignatures timeSignature, bool kiai)
|
protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
// 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 System.Linq;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.Containers
|
||||||
|
{
|
||||||
|
public class ReverseDepthFillFlowContainer<T> : FillFlowContainer<T> where T : Drawable
|
||||||
|
{
|
||||||
|
protected override IComparer<Drawable> DepthComparer => new ReverseCreationOrderDepthComparer();
|
||||||
|
protected override IEnumerable<T> FlowingChildren => base.FlowingChildren.Reverse();
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected override DropdownMenuItem<T> CreateMenuItem(string text, T value) => new OsuDropdownMenuItem(text, value) { AccentColour = AccentColour };
|
protected override DropdownMenuItem<T> CreateMenuItem(string text, T value) => new OsuDropdownMenuItem(text, value) { AccentColour = AccentColour };
|
||||||
|
|
||||||
private class OsuDropdownMenuItem : DropdownMenuItem<T>
|
public class OsuDropdownMenuItem : DropdownMenuItem<T>
|
||||||
{
|
{
|
||||||
public OsuDropdownMenuItem(string text, T current) : base(text, current)
|
public OsuDropdownMenuItem(string text, T current) : base(text, current)
|
||||||
{
|
{
|
||||||
@ -60,7 +60,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
chevron = new TextAwesome
|
Chevron = new TextAwesome
|
||||||
{
|
{
|
||||||
AlwaysPresent = true,
|
AlwaysPresent = true,
|
||||||
Icon = FontAwesome.fa_chevron_right,
|
Icon = FontAwesome.fa_chevron_right,
|
||||||
@ -84,12 +84,12 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
private Color4? accentColour;
|
private Color4? accentColour;
|
||||||
|
|
||||||
private readonly TextAwesome chevron;
|
protected readonly TextAwesome Chevron;
|
||||||
|
|
||||||
protected override void FormatForeground(bool hover = false)
|
protected override void FormatForeground(bool hover = false)
|
||||||
{
|
{
|
||||||
base.FormatForeground(hover);
|
base.FormatForeground(hover);
|
||||||
chevron.Alpha = hover ? 1 : 0;
|
Chevron.Alpha = hover ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
@ -113,13 +113,13 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class OsuDropdownHeader : DropdownHeader
|
public class OsuDropdownHeader : DropdownHeader
|
||||||
{
|
{
|
||||||
private readonly SpriteText label;
|
protected readonly SpriteText Text;
|
||||||
protected override string Label
|
protected override string Label
|
||||||
{
|
{
|
||||||
get { return label.Text; }
|
get { return Text.Text; }
|
||||||
set { label.Text = value; }
|
set { Text.Text = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly TextAwesome Icon;
|
protected readonly TextAwesome Icon;
|
||||||
@ -146,7 +146,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
Foreground.Children = new Drawable[]
|
Foreground.Children = new Drawable[]
|
||||||
{
|
{
|
||||||
label = new OsuSpriteText
|
Text = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
|
32
osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs
Normal file
32
osu.Game/Graphics/UserInterface/OsuEnumDropdown.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;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.UserInterface
|
||||||
|
{
|
||||||
|
public class OsuEnumDropdown<T> : OsuDropdown<T>
|
||||||
|
{
|
||||||
|
public OsuEnumDropdown()
|
||||||
|
{
|
||||||
|
if (!typeof(T).IsEnum)
|
||||||
|
throw new InvalidOperationException("OsuEnumDropdown only supports enums as the generic type argument");
|
||||||
|
|
||||||
|
List<KeyValuePair<string, T>> items = new List<KeyValuePair<string, T>>();
|
||||||
|
foreach(var val in (T[])Enum.GetValues(typeof(T)))
|
||||||
|
{
|
||||||
|
var field = typeof(T).GetField(Enum.GetName(typeof(T), val));
|
||||||
|
items.Add(
|
||||||
|
new KeyValuePair<string, T>(
|
||||||
|
field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? Enum.GetName(typeof(T), val),
|
||||||
|
val
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Items = items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -57,9 +57,9 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OsuTabItem : TabItem<T>
|
public class OsuTabItem : TabItem<T>
|
||||||
{
|
{
|
||||||
private readonly SpriteText text;
|
protected readonly SpriteText Text;
|
||||||
private readonly Box box;
|
private readonly Box box;
|
||||||
|
|
||||||
private Color4? accentColour;
|
private Color4? accentColour;
|
||||||
@ -70,7 +70,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
if (!Active)
|
if (!Active)
|
||||||
text.Colour = value;
|
Text.Colour = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,13 +94,13 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
private void fadeActive()
|
private void fadeActive()
|
||||||
{
|
{
|
||||||
box.FadeIn(transition_length, EasingTypes.OutQuint);
|
box.FadeIn(transition_length, EasingTypes.OutQuint);
|
||||||
text.FadeColour(Color4.White, transition_length, EasingTypes.OutQuint);
|
Text.FadeColour(Color4.White, transition_length, EasingTypes.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fadeInactive()
|
private void fadeInactive()
|
||||||
{
|
{
|
||||||
box.FadeOut(transition_length, EasingTypes.OutQuint);
|
box.FadeOut(transition_length, EasingTypes.OutQuint);
|
||||||
text.FadeColour(AccentColour, transition_length, EasingTypes.OutQuint);
|
Text.FadeColour(AccentColour, transition_length, EasingTypes.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnHover(InputState state)
|
protected override bool OnHover(InputState state)
|
||||||
@ -130,7 +130,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
text = new OsuSpriteText
|
Text = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
|
17
osu.Game/Online/Multiplayer/Room.cs
Normal file
17
osu.Game/Online/Multiplayer/Room.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
|
||||||
|
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.Multiplayer
|
||||||
|
{
|
||||||
|
public class Room
|
||||||
|
{
|
||||||
|
public Bindable<string> Name = new Bindable<string>();
|
||||||
|
public Bindable<User> Host = new Bindable<User>();
|
||||||
|
public Bindable<RoomStatus> Status = new Bindable<RoomStatus>();
|
||||||
|
public Bindable<BeatmapMetadata> Beatmap = new Bindable<BeatmapMetadata>();
|
||||||
|
}
|
||||||
|
}
|
26
osu.Game/Online/Multiplayer/RoomStatus.cs
Normal file
26
osu.Game/Online/Multiplayer/RoomStatus.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// 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.Game.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.Multiplayer
|
||||||
|
{
|
||||||
|
public abstract class RoomStatus
|
||||||
|
{
|
||||||
|
public abstract string Message { get; }
|
||||||
|
public abstract Color4 GetAppropriateColour(OsuColour colours);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RoomStatusOpen : RoomStatus
|
||||||
|
{
|
||||||
|
public override string Message => @"Welcoming Players";
|
||||||
|
public override Color4 GetAppropriateColour(OsuColour colours) => colours.GreenLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RoomStatusPlaying : RoomStatus
|
||||||
|
{
|
||||||
|
public override string Message => @"Now Playing";
|
||||||
|
public override Color4 GetAppropriateColour(OsuColour colours) => colours.Purple;
|
||||||
|
}
|
||||||
|
}
|
@ -41,6 +41,8 @@ namespace osu.Game
|
|||||||
|
|
||||||
private DialogOverlay dialogOverlay;
|
private DialogOverlay dialogOverlay;
|
||||||
|
|
||||||
|
private DirectOverlay direct;
|
||||||
|
|
||||||
private Intro intro
|
private Intro intro
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -70,6 +72,8 @@ namespace osu.Game
|
|||||||
|
|
||||||
public void ToggleSettings() => settings.ToggleVisibility();
|
public void ToggleSettings() => settings.ToggleVisibility();
|
||||||
|
|
||||||
|
public void ToggleDirect() => direct.ToggleVisibility();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
@ -160,6 +164,7 @@ namespace osu.Game
|
|||||||
});
|
});
|
||||||
|
|
||||||
//overlay elements
|
//overlay elements
|
||||||
|
LoadComponentAsync(direct = new DirectOverlay { Depth = -1 }, mainContent.Add);
|
||||||
LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add);
|
LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add);
|
||||||
LoadComponentAsync(settings = new SettingsOverlay { Depth = -1 }, overlayContent.Add);
|
LoadComponentAsync(settings = new SettingsOverlay { Depth = -1 }, overlayContent.Add);
|
||||||
LoadComponentAsync(musicController = new MusicController
|
LoadComponentAsync(musicController = new MusicController
|
||||||
@ -249,6 +254,9 @@ namespace osu.Game
|
|||||||
case Key.O:
|
case Key.O:
|
||||||
settings.ToggleVisibility();
|
settings.ToggleVisibility();
|
||||||
return true;
|
return true;
|
||||||
|
case Key.D:
|
||||||
|
direct.ToggleVisibility();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,6 +288,7 @@ namespace osu.Game
|
|||||||
Toolbar.State = Visibility.Hidden;
|
Toolbar.State = Visibility.Hidden;
|
||||||
musicController.State = Visibility.Hidden;
|
musicController.State = Visibility.Hidden;
|
||||||
chat.State = Visibility.Hidden;
|
chat.State = Visibility.Hidden;
|
||||||
|
direct.State = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
193
osu.Game/Overlays/Direct/DirectGridPanel.cs
Normal file
193
osu.Game/Overlays/Direct/DirectGridPanel.cs
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Direct
|
||||||
|
{
|
||||||
|
public class DirectGridPanel : DirectPanel
|
||||||
|
{
|
||||||
|
private const float horizontal_padding = 10;
|
||||||
|
private const float vertical_padding = 5;
|
||||||
|
|
||||||
|
private FillFlowContainer bottomPanel;
|
||||||
|
|
||||||
|
public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap)
|
||||||
|
{
|
||||||
|
Height = 140 + vertical_padding; //full height of all the elements plus vertical padding (autosize uses the image)
|
||||||
|
CornerRadius = 4;
|
||||||
|
Masking = true;
|
||||||
|
|
||||||
|
EdgeEffect = new EdgeEffect
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Offset = new Vector2(0f, 1f),
|
||||||
|
Radius = 3f,
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
FadeInFromZero(200, EasingTypes.Out);
|
||||||
|
bottomPanel.LayoutDuration = 200;
|
||||||
|
bottomPanel.LayoutEasing = EasingTypes.Out;
|
||||||
|
bottomPanel.Origin = Anchor.BottomLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours, LocalisationEngine localisation, TextureStore textures)
|
||||||
|
{
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
},
|
||||||
|
GetBackground(textures),
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black.Opacity(0.5f),
|
||||||
|
},
|
||||||
|
bottomPanel = new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Spacing = new Vector2(0f, vertical_padding),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Left = horizontal_padding, Right = horizontal_padding },
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title),
|
||||||
|
TextSize = 18,
|
||||||
|
Font = @"Exo2.0-BoldItalic",
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist),
|
||||||
|
Font = @"Exo2.0-BoldItalic",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Padding = new MarginPadding
|
||||||
|
{
|
||||||
|
Top = vertical_padding,
|
||||||
|
Bottom = vertical_padding,
|
||||||
|
Left = horizontal_padding,
|
||||||
|
Right = horizontal_padding,
|
||||||
|
},
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = "mapped by ",
|
||||||
|
TextSize = 14,
|
||||||
|
Shadow = false,
|
||||||
|
Colour = colours.Gray5,
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = SetInfo.Metadata.Author,
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-SemiBoldItalic",
|
||||||
|
Shadow = false,
|
||||||
|
Colour = colours.BlueDark,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
Height = 14,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = $"from {SetInfo.Metadata.Source}",
|
||||||
|
TextSize = 14,
|
||||||
|
Shadow = false,
|
||||||
|
Colour = colours.Gray5,
|
||||||
|
Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
Height = 20,
|
||||||
|
Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding },
|
||||||
|
Children = GetDifficultyIcons(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Margin = new MarginPadding { Top = vertical_padding, Right = vertical_padding },
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new Statistic(FontAwesome.fa_play_circle, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.PlayCount ?? 0)
|
||||||
|
{
|
||||||
|
Margin = new MarginPadding { Right = 1 },
|
||||||
|
},
|
||||||
|
new Statistic(FontAwesome.fa_heart, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.FavouriteCount ?? 0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
197
osu.Game/Overlays/Direct/DirectListPanel.cs
Normal file
197
osu.Game/Overlays/Direct/DirectListPanel.cs
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
// 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.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Direct
|
||||||
|
{
|
||||||
|
public class DirectListPanel : DirectPanel
|
||||||
|
{
|
||||||
|
private const float horizontal_padding = 10;
|
||||||
|
private const float vertical_padding = 5;
|
||||||
|
private const float height = 70;
|
||||||
|
|
||||||
|
public DirectListPanel(BeatmapSetInfo beatmap) : base(beatmap)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
Height = height;
|
||||||
|
CornerRadius = 5;
|
||||||
|
Masking = true;
|
||||||
|
EdgeEffect = new EdgeEffect
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Offset = new Vector2(0f, 1f),
|
||||||
|
Radius = 3f,
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
FadeInFromZero(200, EasingTypes.Out);
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(LocalisationEngine localisation, TextureStore textures)
|
||||||
|
{
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
},
|
||||||
|
GetBackground(textures),
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
ColourInfo = ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.25f), Color4.Black.Opacity(0.75f)),
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding, Left = horizontal_padding, Right = vertical_padding },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Margin = new MarginPadding { Right = height - vertical_padding * 2 + vertical_padding },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Statistic(FontAwesome.fa_play_circle, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.PlayCount ?? 0)
|
||||||
|
{
|
||||||
|
Margin = new MarginPadding { Right = 1 },
|
||||||
|
},
|
||||||
|
new Statistic(FontAwesome.fa_heart, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.FavouriteCount ?? 0),
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = "mapped by ",
|
||||||
|
TextSize = 14,
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = SetInfo.Metadata.Author,
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-SemiBoldItalic",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = $"from {SetInfo.Metadata.Source}",
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
TextSize = 14,
|
||||||
|
Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new DownloadButton
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Size = new Vector2(height - vertical_padding * 2),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DownloadButton : ClickableContainer
|
||||||
|
{
|
||||||
|
private readonly TextAwesome icon;
|
||||||
|
|
||||||
|
public DownloadButton()
|
||||||
|
{
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
icon = new TextAwesome
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
UseFullGlyphHeight = false,
|
||||||
|
TextSize = 30,
|
||||||
|
Icon = FontAwesome.fa_osu_chevron_down_o,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
|
{
|
||||||
|
icon.ScaleTo(0.9f, 1000, EasingTypes.Out);
|
||||||
|
return base.OnMouseDown(state, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||||
|
{
|
||||||
|
icon.ScaleTo(1f, 500, EasingTypes.OutElastic);
|
||||||
|
return base.OnMouseUp(state, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(InputState state)
|
||||||
|
{
|
||||||
|
icon.ScaleTo(1.1f, 500, EasingTypes.OutElastic);
|
||||||
|
return base.OnHover(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(InputState state)
|
||||||
|
{
|
||||||
|
icon.ScaleTo(1f, 500, EasingTypes.OutElastic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
osu.Game/Overlays/Direct/DirectPanel.cs
Normal file
88
osu.Game/Overlays/Direct/DirectPanel.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 System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenTK;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Beatmaps.Drawables;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Direct
|
||||||
|
{
|
||||||
|
public abstract class DirectPanel : Container
|
||||||
|
{
|
||||||
|
protected readonly BeatmapSetInfo SetInfo;
|
||||||
|
|
||||||
|
protected DirectPanel(BeatmapSetInfo setInfo)
|
||||||
|
{
|
||||||
|
SetInfo = setInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<DifficultyIcon> GetDifficultyIcons()
|
||||||
|
{
|
||||||
|
var icons = new List<DifficultyIcon>();
|
||||||
|
|
||||||
|
foreach (var b in SetInfo.Beatmaps)
|
||||||
|
icons.Add(new DifficultyIcon(b));
|
||||||
|
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Drawable GetBackground(TextureStore textures)
|
||||||
|
{
|
||||||
|
return new AsyncLoadWrapper(new BeatmapBackgroundSprite(new OnlineWorkingBeatmap(SetInfo.Beatmaps.FirstOrDefault(), textures, null))
|
||||||
|
{
|
||||||
|
FillMode = FillMode.Fill,
|
||||||
|
OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out),
|
||||||
|
}) { RelativeSizeAxes = Axes.Both };
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Statistic : FillFlowContainer
|
||||||
|
{
|
||||||
|
private readonly SpriteText text;
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
public int Value
|
||||||
|
{
|
||||||
|
get { return value; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
text.Text = Value.ToString(@"N0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statistic(FontAwesome icon, int value = 0)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight;
|
||||||
|
Origin = Anchor.TopRight;
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
Direction = FillDirection.Horizontal;
|
||||||
|
Spacing = new Vector2(5f, 0f);
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
text = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Font = @"Exo2.0-SemiBoldItalic",
|
||||||
|
},
|
||||||
|
new TextAwesome
|
||||||
|
{
|
||||||
|
Icon = icon,
|
||||||
|
Shadow = true,
|
||||||
|
TextSize = 14,
|
||||||
|
Margin = new MarginPadding { Top = 1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
233
osu.Game/Overlays/Direct/FilterControl.cs
Normal file
233
osu.Game/Overlays/Direct/FilterControl.cs
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
// 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.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Direct
|
||||||
|
{
|
||||||
|
public class FilterControl : Container
|
||||||
|
{
|
||||||
|
public static readonly float HEIGHT = 35 + 32 + 30 + padding * 2; // search + mode toggle buttons + sort tabs + padding
|
||||||
|
|
||||||
|
private const float padding = 10;
|
||||||
|
|
||||||
|
private readonly Box tabStrip;
|
||||||
|
private readonly FillFlowContainer<RulesetToggleButton> modeButtons;
|
||||||
|
|
||||||
|
public readonly SearchTextBox Search;
|
||||||
|
public readonly SortTabControl SortTabs;
|
||||||
|
public readonly OsuEnumDropdown<RankStatus> RankStatusDropdown;
|
||||||
|
public readonly Bindable<DirectOverlay.PanelDisplayStyle> DisplayStyle = new Bindable<DirectOverlay.PanelDisplayStyle>();
|
||||||
|
|
||||||
|
protected override bool InternalContains(Vector2 screenSpacePos) => base.InternalContains(screenSpacePos) || RankStatusDropdown.Contains(screenSpacePos);
|
||||||
|
|
||||||
|
public FilterControl()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
Height = HEIGHT;
|
||||||
|
DisplayStyle.Value = DirectOverlay.PanelDisplayStyle.Grid;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.FromHex(@"384552"),
|
||||||
|
Alpha = 0.9f,
|
||||||
|
},
|
||||||
|
tabStrip = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 1,
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Padding = new MarginPadding { Left = DirectOverlay.WIDTH_PADDING, Right = DirectOverlay.WIDTH_PADDING },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
Search = new DirectSearchTextBox
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Margin = new MarginPadding { Top = padding },
|
||||||
|
},
|
||||||
|
modeButtons = new FillFlowContainer<RulesetToggleButton>
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Spacing = new Vector2(padding, 0f),
|
||||||
|
Margin = new MarginPadding { Top = padding },
|
||||||
|
},
|
||||||
|
SortTabs = new SortTabControl
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Spacing = new Vector2(10f, 0f),
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Margin = new MarginPadding { Top = HEIGHT - SlimEnumDropdown<DirectTab>.HEIGHT - padding, Right = DirectOverlay.WIDTH_PADDING },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Spacing = new Vector2(5f, 0f),
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new DisplayStyleToggleButton(FontAwesome.fa_th_large, DirectOverlay.PanelDisplayStyle.Grid, DisplayStyle),
|
||||||
|
new DisplayStyleToggleButton(FontAwesome.fa_list_ul, DirectOverlay.PanelDisplayStyle.List, DisplayStyle),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RankStatusDropdown = new SlimEnumDropdown<RankStatus>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.None,
|
||||||
|
Width = 160f,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
RankStatusDropdown.Current.Value = RankStatus.RankedApproved;
|
||||||
|
SortTabs.Current.Value = SortCriteria.Title;
|
||||||
|
SortTabs.Current.TriggerChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(true)]
|
||||||
|
private void load(OsuGame game, RulesetDatabase rulesets, OsuColour colours)
|
||||||
|
{
|
||||||
|
tabStrip.Colour = colours.Yellow;
|
||||||
|
RankStatusDropdown.AccentColour = colours.BlueDark;
|
||||||
|
|
||||||
|
var b = new Bindable<RulesetInfo>(); //backup bindable incase the game is null
|
||||||
|
foreach (var r in rulesets.AllRulesets)
|
||||||
|
{
|
||||||
|
modeButtons.Add(new RulesetToggleButton(game?.Ruleset ?? b, r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DirectSearchTextBox : SearchTextBox
|
||||||
|
{
|
||||||
|
protected override Color4 BackgroundUnfocused => backgroundColour;
|
||||||
|
protected override Color4 BackgroundFocused => backgroundColour;
|
||||||
|
|
||||||
|
private Color4 backgroundColour;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
backgroundColour = colours.Gray2.Opacity(0.9f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RulesetToggleButton : ClickableContainer
|
||||||
|
{
|
||||||
|
private readonly TextAwesome icon;
|
||||||
|
|
||||||
|
private RulesetInfo ruleset;
|
||||||
|
public RulesetInfo Ruleset
|
||||||
|
{
|
||||||
|
get { return ruleset; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ruleset = value;
|
||||||
|
icon.Icon = Ruleset.CreateInstance().Icon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Bindable<RulesetInfo> bindable;
|
||||||
|
|
||||||
|
private void Bindable_ValueChanged(RulesetInfo obj)
|
||||||
|
{
|
||||||
|
icon.FadeTo(Ruleset.ID == obj?.ID ? 1f : 0.5f, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RulesetToggleButton(Bindable<RulesetInfo> bindable, RulesetInfo ruleset)
|
||||||
|
{
|
||||||
|
this.bindable = bindable;
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
icon = new TextAwesome
|
||||||
|
{
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
TextSize = 32,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ruleset = ruleset;
|
||||||
|
bindable.ValueChanged += Bindable_ValueChanged;
|
||||||
|
Bindable_ValueChanged(bindable.Value);
|
||||||
|
Action = () => bindable.Value = Ruleset;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
if (bindable != null)
|
||||||
|
bindable.ValueChanged -= Bindable_ValueChanged;
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DisplayStyleToggleButton : ClickableContainer
|
||||||
|
{
|
||||||
|
private readonly TextAwesome icon;
|
||||||
|
private readonly DirectOverlay.PanelDisplayStyle style;
|
||||||
|
private readonly Bindable<DirectOverlay.PanelDisplayStyle> bindable;
|
||||||
|
|
||||||
|
public DisplayStyleToggleButton(FontAwesome icon, DirectOverlay.PanelDisplayStyle style, Bindable<DirectOverlay.PanelDisplayStyle> bindable)
|
||||||
|
{
|
||||||
|
this.bindable = bindable;
|
||||||
|
this.style = style;
|
||||||
|
Size = new Vector2(SlimEnumDropdown<DirectTab>.HEIGHT);
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
this.icon = new TextAwesome
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Icon = icon,
|
||||||
|
TextSize = 18,
|
||||||
|
UseFullGlyphHeight = false,
|
||||||
|
Alpha = 0.5f,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
bindable.ValueChanged += Bindable_ValueChanged;
|
||||||
|
Bindable_ValueChanged(bindable.Value);
|
||||||
|
Action = () => bindable.Value = this.style;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Bindable_ValueChanged(DirectOverlay.PanelDisplayStyle style)
|
||||||
|
{
|
||||||
|
icon.FadeTo(style == this.style ? 1.0f : 0.5f, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
bindable.ValueChanged -= Bindable_ValueChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
124
osu.Game/Overlays/Direct/Header.cs
Normal file
124
osu.Game/Overlays/Direct/Header.cs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// 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.ComponentModel;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
|
using Container = osu.Framework.Graphics.Containers.Container;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Direct
|
||||||
|
{
|
||||||
|
public class Header : Container
|
||||||
|
{
|
||||||
|
public static readonly float HEIGHT = 90;
|
||||||
|
|
||||||
|
private readonly Box tabStrip;
|
||||||
|
|
||||||
|
public readonly OsuTabControl<DirectTab> Tabs;
|
||||||
|
|
||||||
|
public Header()
|
||||||
|
{
|
||||||
|
Height = HEIGHT;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.FromHex(@"252f3a"),
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Left = DirectOverlay.WIDTH_PADDING, Right = DirectOverlay.WIDTH_PADDING },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Position = new Vector2(-35f, 5f),
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Spacing = new Vector2(10f, 0f),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new TextAwesome
|
||||||
|
{
|
||||||
|
TextSize = 25,
|
||||||
|
Icon = FontAwesome.fa_osu_chevron_down_o,
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
TextSize = 25,
|
||||||
|
Text = @"osu!direct",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tabStrip = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Width = 282, //todo: make this actually match the tab control's width instead of hardcoding
|
||||||
|
Height = 1,
|
||||||
|
},
|
||||||
|
Tabs = new DirectTabControl
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Tabs.Current.Value = DirectTab.Search;
|
||||||
|
Tabs.Current.TriggerChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
tabStrip.Colour = colours.Green;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DirectTabControl : OsuTabControl<DirectTab>
|
||||||
|
{
|
||||||
|
protected override TabItem<DirectTab> CreateTabItem(DirectTab value) => new DirectTabItem(value);
|
||||||
|
|
||||||
|
public DirectTabControl()
|
||||||
|
{
|
||||||
|
Height = 25;
|
||||||
|
AccentColour = Color4.White;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DirectTabItem : OsuTabItem
|
||||||
|
{
|
||||||
|
public DirectTabItem(DirectTab value) : base(value)
|
||||||
|
{
|
||||||
|
Text.TextSize = 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DirectTab
|
||||||
|
{
|
||||||
|
Search,
|
||||||
|
[Description("Newest Maps")]
|
||||||
|
NewestMaps,
|
||||||
|
[Description("Top Rated")]
|
||||||
|
TopRated,
|
||||||
|
[Description("Most Played")]
|
||||||
|
MostPlayed
|
||||||
|
}
|
||||||
|
}
|
43
osu.Game/Overlays/Direct/SlimEnumDropdown.cs
Normal file
43
osu.Game/Overlays/Direct/SlimEnumDropdown.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 OpenTK.Graphics;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Direct
|
||||||
|
{
|
||||||
|
public class SlimEnumDropdown<T> : OsuEnumDropdown<T>
|
||||||
|
{
|
||||||
|
public const float HEIGHT = 25;
|
||||||
|
|
||||||
|
protected override DropdownHeader CreateHeader() => new SlimDropdownHeader { AccentColour = AccentColour };
|
||||||
|
protected override Menu CreateMenu() => new SlimMenu();
|
||||||
|
|
||||||
|
private class SlimDropdownHeader : OsuDropdownHeader
|
||||||
|
{
|
||||||
|
public SlimDropdownHeader()
|
||||||
|
{
|
||||||
|
Height = HEIGHT;
|
||||||
|
Icon.TextSize = 16;
|
||||||
|
Foreground.Padding = new MarginPadding { Top = 4, Bottom = 4, Left = 8, Right = 4 };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
BackgroundColour = Color4.Black.Opacity(0.25f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SlimMenu : OsuMenu
|
||||||
|
{
|
||||||
|
public SlimMenu()
|
||||||
|
{
|
||||||
|
Background.Colour = Color4.Black.Opacity(0.25f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
osu.Game/Overlays/Direct/SortTabControl.cs
Normal file
117
osu.Game/Overlays/Direct/SortTabControl.cs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Direct
|
||||||
|
{
|
||||||
|
public class SortTabControl : OsuTabControl<SortCriteria>
|
||||||
|
{
|
||||||
|
protected override TabItem<SortCriteria> CreateTabItem(SortCriteria value) => new SortTabItem(value);
|
||||||
|
|
||||||
|
public SortTabControl()
|
||||||
|
{
|
||||||
|
Height = 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SortTabItem : TabItem<SortCriteria>
|
||||||
|
{
|
||||||
|
private const float transition_duration = 100;
|
||||||
|
|
||||||
|
private readonly Box box;
|
||||||
|
|
||||||
|
public override bool Active
|
||||||
|
{
|
||||||
|
get { return base.Active; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Active == value) return;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
slideActive();
|
||||||
|
else
|
||||||
|
slideInactive();
|
||||||
|
base.Active = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortTabItem(SortCriteria value) : base(value)
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.X;
|
||||||
|
RelativeSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Margin = new MarginPadding { Top = 8, Bottom = 8 },
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Text = (value as Enum).GetDescription() ?? value.ToString(),
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-Bold",
|
||||||
|
},
|
||||||
|
box = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 5,
|
||||||
|
Scale = new Vector2(1f, 0f),
|
||||||
|
Colour = Color4.White,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
box.Colour = colours.Yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(InputState state)
|
||||||
|
{
|
||||||
|
if (!Active)
|
||||||
|
slideActive();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(InputState state)
|
||||||
|
{
|
||||||
|
if (!Active)
|
||||||
|
slideInactive();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void slideActive()
|
||||||
|
{
|
||||||
|
box.ScaleTo(new Vector2(1f), transition_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void slideInactive()
|
||||||
|
{
|
||||||
|
box.ScaleTo(new Vector2(1f, 0f), transition_duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SortCriteria
|
||||||
|
{
|
||||||
|
Title,
|
||||||
|
Artist,
|
||||||
|
Creator,
|
||||||
|
Difficulty,
|
||||||
|
Ranked,
|
||||||
|
Rating,
|
||||||
|
}
|
||||||
|
}
|
230
osu.Game/Overlays/DirectOverlay.cs
Normal file
230
osu.Game/Overlays/DirectOverlay.cs
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
// 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 System.Linq;
|
||||||
|
using OpenTK;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Backgrounds;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Overlays.Direct;
|
||||||
|
|
||||||
|
using Container = osu.Framework.Graphics.Containers.Container;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays
|
||||||
|
{
|
||||||
|
public class DirectOverlay : WaveOverlayContainer
|
||||||
|
{
|
||||||
|
public static readonly int WIDTH_PADDING = 80;
|
||||||
|
private const float panel_padding = 10f;
|
||||||
|
|
||||||
|
private readonly FilterControl filter;
|
||||||
|
private readonly FillFlowContainer resultCountsContainer;
|
||||||
|
private readonly OsuSpriteText resultCountsText;
|
||||||
|
private readonly FillFlowContainer<DirectPanel> panels;
|
||||||
|
|
||||||
|
private IEnumerable<BeatmapSetInfo> beatmapSets;
|
||||||
|
public IEnumerable<BeatmapSetInfo> BeatmapSets
|
||||||
|
{
|
||||||
|
get { return beatmapSets; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (beatmapSets?.Equals(value) ?? false) return;
|
||||||
|
beatmapSets = value;
|
||||||
|
|
||||||
|
recreatePanels(filter.DisplayStyle.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultCounts resultAmounts;
|
||||||
|
public ResultCounts ResultAmounts
|
||||||
|
{
|
||||||
|
get { return resultAmounts; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == ResultAmounts) return;
|
||||||
|
resultAmounts = value;
|
||||||
|
|
||||||
|
updateResultCounts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirectOverlay()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
// osu!direct colours are not part of the standard palette
|
||||||
|
|
||||||
|
FirstWaveColour = OsuColour.FromHex(@"19b0e2");
|
||||||
|
SecondWaveColour = OsuColour.FromHex(@"2280a2");
|
||||||
|
ThirdWaveColour = OsuColour.FromHex(@"005774");
|
||||||
|
FourthWaveColour = OsuColour.FromHex(@"003a4e");
|
||||||
|
|
||||||
|
Header header;
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.FromHex(@"485e74"),
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Masking = true,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new Triangles
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
TriangleScale = 5,
|
||||||
|
ColourLight = OsuColour.FromHex(@"465b71"),
|
||||||
|
ColourDark = OsuColour.FromHex(@"3f5265"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Top = Header.HEIGHT + FilterControl.HEIGHT },
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new ScrollContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
ScrollDraggerVisible = false,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
resultCountsContainer = new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Margin = new MarginPadding { Left = WIDTH_PADDING, Top = 6 },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = "Found ",
|
||||||
|
TextSize = 15,
|
||||||
|
},
|
||||||
|
resultCountsText = new OsuSpriteText
|
||||||
|
{
|
||||||
|
TextSize = 15,
|
||||||
|
Font = @"Exo2.0-Bold",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
panels = new FillFlowContainer<DirectPanel>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Padding = new MarginPadding { Top = panel_padding, Bottom = panel_padding, Left = WIDTH_PADDING, Right = WIDTH_PADDING },
|
||||||
|
Spacing = new Vector2(panel_padding),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filter = new FilterControl
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Margin = new MarginPadding { Top = Header.HEIGHT },
|
||||||
|
},
|
||||||
|
header = new Header
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
header.Tabs.Current.ValueChanged += tab => { if (tab != DirectTab.Search) filter.Search.Current.Value = string.Empty; };
|
||||||
|
|
||||||
|
filter.Search.Exit = Hide;
|
||||||
|
filter.Search.Current.ValueChanged += text => { if (text != string.Empty) header.Tabs.Current.Value = DirectTab.Search; };
|
||||||
|
filter.DisplayStyle.ValueChanged += recreatePanels;
|
||||||
|
|
||||||
|
updateResultCounts();
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
resultCountsContainer.Colour = colours.Yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateResultCounts()
|
||||||
|
{
|
||||||
|
resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, EasingTypes.Out);
|
||||||
|
if (ResultAmounts == null) return;
|
||||||
|
|
||||||
|
resultCountsText.Text = pluralize("Artist", ResultAmounts.Artists) + ", " +
|
||||||
|
pluralize("Song", ResultAmounts.Songs) + ", " +
|
||||||
|
pluralize("Tag", ResultAmounts.Tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string pluralize(string prefix, int value)
|
||||||
|
{
|
||||||
|
return $@"{value} {prefix}" + (value == 1 ? string.Empty : @"s");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recreatePanels(PanelDisplayStyle displayStyle)
|
||||||
|
{
|
||||||
|
if (BeatmapSets == null) return;
|
||||||
|
panels.Children = BeatmapSets.Select(b => displayStyle == PanelDisplayStyle.Grid ? (DirectPanel)new DirectGridPanel(b) { Width = 400 } : new DirectListPanel(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnFocus(InputState state)
|
||||||
|
{
|
||||||
|
filter.Search.TriggerFocus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopIn()
|
||||||
|
{
|
||||||
|
base.PopIn();
|
||||||
|
|
||||||
|
filter.Search.HoldFocus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopOut()
|
||||||
|
{
|
||||||
|
base.PopOut();
|
||||||
|
|
||||||
|
filter.Search.HoldFocus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ResultCounts
|
||||||
|
{
|
||||||
|
public readonly int Artists;
|
||||||
|
public readonly int Songs;
|
||||||
|
public readonly int Tags;
|
||||||
|
|
||||||
|
public ResultCounts(int artists, int songs, int tags)
|
||||||
|
{
|
||||||
|
Artists = artists;
|
||||||
|
Songs = songs;
|
||||||
|
Tags = tags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PanelDisplayStyle
|
||||||
|
{
|
||||||
|
Grid,
|
||||||
|
List,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,15 +12,24 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
|
||||||
|
using Container = osu.Framework.Graphics.Containers.Container;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.General
|
namespace osu.Game.Overlays.Settings.Sections.General
|
||||||
{
|
{
|
||||||
public class LoginSettings : SettingsSubsection, IOnlineComponent
|
public class LoginSettings : FillFlowContainer, IOnlineComponent
|
||||||
{
|
{
|
||||||
private bool bounding = true;
|
private bool bounding = true;
|
||||||
private LoginForm form;
|
private LoginForm form;
|
||||||
|
private OsuColour colours;
|
||||||
|
|
||||||
protected override string Header => "Account";
|
private UserPanel panel;
|
||||||
|
private UserDropdown dropdown;
|
||||||
|
|
||||||
public override RectangleF BoundingBox => bounding ? base.BoundingBox : RectangleF.Empty;
|
public override RectangleF BoundingBox => bounding ? base.BoundingBox : RectangleF.Empty;
|
||||||
|
|
||||||
@ -34,9 +43,18 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
public LoginSettings()
|
||||||
private void load(APIAccess api)
|
|
||||||
{
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
Direction = FillDirection.Vertical;
|
||||||
|
Spacing = new Vector2(0f, 5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
|
private void load(OsuColour colours, APIAccess api)
|
||||||
|
{
|
||||||
|
this.colours = colours;
|
||||||
api?.Register(this);
|
api?.Register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +67,12 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
case APIState.Offline:
|
case APIState.Offline:
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = "ACCOUNT",
|
||||||
|
Margin = new MarginPadding { Bottom = 5 },
|
||||||
|
Font = @"Exo2.0-Black",
|
||||||
|
},
|
||||||
form = new LoginForm()
|
form = new LoginForm()
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
@ -66,24 +90,73 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
{
|
{
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
Text = "Connecting...",
|
Text = "Connecting...",
|
||||||
|
Margin = new MarginPadding { Top = 10, Bottom = 10 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case APIState.Online:
|
case APIState.Online:
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new OsuSpriteText
|
new FillFlowContainer
|
||||||
{
|
|
||||||
Text = $"Connected as {api.Username}!",
|
|
||||||
},
|
|
||||||
new OsuButton
|
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Text = "Sign out",
|
AutoSizeAxes = Axes.Y,
|
||||||
Action = api.Logout
|
Padding = new MarginPadding { Left = 20, Right = 20 },
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0f, 10f),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Text = "Signed in",
|
||||||
|
TextSize = 18,
|
||||||
|
Font = @"Exo2.0-Bold",
|
||||||
|
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
panel = new UserPanel(api.LocalUser.Value) { RelativeSizeAxes = Axes.X },
|
||||||
|
dropdown = new UserDropdown { RelativeSizeAxes = Axes.X },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
panel.Status.BindTo(api.LocalUser.Value.Status);
|
||||||
|
|
||||||
|
dropdown.Current.ValueChanged += newValue =>
|
||||||
|
{
|
||||||
|
switch (newValue)
|
||||||
|
{
|
||||||
|
case UserAction.Online:
|
||||||
|
api.LocalUser.Value.Status.Value = new UserStatusOnline();
|
||||||
|
dropdown.StatusColour = colours.Green;
|
||||||
|
break;
|
||||||
|
case UserAction.DoNotDisturb:
|
||||||
|
api.LocalUser.Value.Status.Value = new UserStatusDoNotDisturb();
|
||||||
|
dropdown.StatusColour = colours.Red;
|
||||||
|
break;
|
||||||
|
case UserAction.AppearOffline:
|
||||||
|
api.LocalUser.Value.Status.Value = new UserStatusOffline();
|
||||||
|
dropdown.StatusColour = colours.Gray7;
|
||||||
|
break;
|
||||||
|
case UserAction.SignOut:
|
||||||
|
api.Logout();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
dropdown.Current.TriggerChange();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,5 +243,119 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
return base.OnFocus(state);
|
return base.OnFocus(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class UserDropdown : OsuEnumDropdown<UserAction>
|
||||||
|
{
|
||||||
|
protected override DropdownHeader CreateHeader() => new UserDropdownHeader { AccentColour = AccentColour };
|
||||||
|
protected override Menu CreateMenu() => new UserDropdownMenu();
|
||||||
|
protected override DropdownMenuItem<UserAction> CreateMenuItem(string text, UserAction value) => new UserDropdownMenuItem(text, value) { AccentColour = AccentColour };
|
||||||
|
|
||||||
|
public Color4 StatusColour
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
var h = Header as UserDropdownHeader;
|
||||||
|
if (h == null) return;
|
||||||
|
h.StatusColour = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
AccentColour = colours.Gray5;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UserDropdownHeader : OsuDropdownHeader
|
||||||
|
{
|
||||||
|
public const float LABEL_LEFT_MARGIN = 20;
|
||||||
|
|
||||||
|
private readonly TextAwesome statusIcon;
|
||||||
|
public Color4 StatusColour
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
statusIcon.FadeColour(value, 500, EasingTypes.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserDropdownHeader()
|
||||||
|
{
|
||||||
|
Foreground.Padding = new MarginPadding { Left = 10, Right = 10 };
|
||||||
|
Margin = new MarginPadding { Bottom = 5 };
|
||||||
|
Masking = true;
|
||||||
|
CornerRadius = 5;
|
||||||
|
EdgeEffect = new EdgeEffect
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
Radius = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
Icon.TextSize = 14;
|
||||||
|
Icon.Margin = new MarginPadding(0);
|
||||||
|
|
||||||
|
Foreground.Add(statusIcon = new TextAwesome
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Icon = FontAwesome.fa_circle_o,
|
||||||
|
TextSize = 14,
|
||||||
|
});
|
||||||
|
|
||||||
|
Text.Margin = new MarginPadding { Left = LABEL_LEFT_MARGIN };
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
BackgroundColour = colours.Gray3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UserDropdownMenu : OsuMenu
|
||||||
|
{
|
||||||
|
public UserDropdownMenu()
|
||||||
|
{
|
||||||
|
Margin = new MarginPadding { Bottom = 5 };
|
||||||
|
CornerRadius = 5;
|
||||||
|
ItemsContainer.Padding = new MarginPadding(0);
|
||||||
|
Masking = true;
|
||||||
|
EdgeEffect = new EdgeEffect
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
Radius = 4,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
Background.Colour = colours.Gray3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UserDropdownMenuItem : OsuDropdownMenuItem
|
||||||
|
{
|
||||||
|
public UserDropdownMenuItem(string text, UserAction current) : base(text, current)
|
||||||
|
{
|
||||||
|
Foreground.Padding = new MarginPadding { Top = 5, Bottom = 5, Left = UserDropdownHeader.LABEL_LEFT_MARGIN, Right = 5 };
|
||||||
|
Chevron.Margin = new MarginPadding { Left = 2, Right = 3 };
|
||||||
|
CornerRadius = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum UserAction
|
||||||
|
{
|
||||||
|
Online,
|
||||||
|
[Description(@"Do not disturb")]
|
||||||
|
DoNotDisturb,
|
||||||
|
[Description(@"Appear offline")]
|
||||||
|
AppearOffline,
|
||||||
|
[Description(@"Sign out")]
|
||||||
|
SignOut,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,17 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using osu.Framework.Graphics;
|
||||||
using System.Reflection;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings
|
namespace osu.Game.Overlays.Settings
|
||||||
{
|
{
|
||||||
public class SettingsEnumDropdown<T> : SettingsDropdown<T>
|
public class SettingsEnumDropdown<T> : SettingsDropdown<T>
|
||||||
{
|
{
|
||||||
public SettingsEnumDropdown()
|
protected override Drawable CreateControl() => new OsuEnumDropdown<T>
|
||||||
{
|
{
|
||||||
if (!typeof(T).IsEnum)
|
Margin = new MarginPadding { Top = 5 },
|
||||||
throw new InvalidOperationException("SettingsDropdown only supports enums as the generic type argument");
|
RelativeSizeAxes = Axes.X,
|
||||||
|
};
|
||||||
List<KeyValuePair<string, T>> items = new List<KeyValuePair<string, T>>();
|
|
||||||
foreach(var val in (T[])Enum.GetValues(typeof(T)))
|
|
||||||
{
|
|
||||||
var field = typeof(T).GetField(Enum.GetName(typeof(T), val));
|
|
||||||
items.Add(
|
|
||||||
new KeyValuePair<string, T>(
|
|
||||||
field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? Enum.GetName(typeof(T), val),
|
|
||||||
val
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Items = items;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
OnSolo = delegate { Push(consumeSongSelect()); },
|
OnSolo = delegate { Push(consumeSongSelect()); },
|
||||||
OnMulti = delegate { Push(new Lobby()); },
|
OnMulti = delegate { Push(new Lobby()); },
|
||||||
OnExit = delegate { Exit(); },
|
OnExit = delegate { Exit(); },
|
||||||
}
|
},
|
||||||
|
new MenuSideFlashes(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -60,6 +61,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
LoadComponentAsync(background);
|
LoadComponentAsync(background);
|
||||||
|
|
||||||
buttons.OnSettings = game.ToggleSettings;
|
buttons.OnSettings = game.ToggleSettings;
|
||||||
|
buttons.OnDirect = game.ToggleDirect;
|
||||||
|
|
||||||
preloadSongSelect();
|
preloadSongSelect();
|
||||||
}
|
}
|
||||||
|
98
osu.Game/Screens/Menu/MenuSideFlashes.cs
Normal file
98
osu.Game/Screens/Menu/MenuSideFlashes.cs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// 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.Track;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Menu
|
||||||
|
{
|
||||||
|
public class MenuSideFlashes : BeatSyncedContainer
|
||||||
|
{
|
||||||
|
public override bool HandleInput => false;
|
||||||
|
|
||||||
|
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||||
|
|
||||||
|
private readonly Box leftBox;
|
||||||
|
private readonly Box rightBox;
|
||||||
|
|
||||||
|
private const float amplitude_dead_zone = 0.25f;
|
||||||
|
private const float alpha_multiplier = (1 - amplitude_dead_zone) / 0.55f;
|
||||||
|
private const float kiai_multiplier = (1 - amplitude_dead_zone * 0.95f) / 0.8f;
|
||||||
|
|
||||||
|
private const int box_max_alpha = 200;
|
||||||
|
private const double box_fade_in_time = 65;
|
||||||
|
private const int box_width = 200;
|
||||||
|
|
||||||
|
public MenuSideFlashes()
|
||||||
|
{
|
||||||
|
EarlyActivationMilliseconds = box_fade_in_time;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
Anchor = Anchor.Centre;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
leftBox = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Width = box_width,
|
||||||
|
Alpha = 0,
|
||||||
|
BlendingMode = BlendingMode.Additive,
|
||||||
|
},
|
||||||
|
rightBox = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreRight,
|
||||||
|
Origin = Anchor.CentreRight,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Width = box_width,
|
||||||
|
Alpha = 0,
|
||||||
|
BlendingMode = BlendingMode.Additive,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuGameBase game, OsuColour colours)
|
||||||
|
{
|
||||||
|
beatmap.BindTo(game.Beatmap);
|
||||||
|
|
||||||
|
// linear colour looks better in this case, so let's use it for now.
|
||||||
|
Color4 gradientDark = colours.Blue.Opacity(0).ToLinear();
|
||||||
|
Color4 gradientLight = colours.Blue.Opacity(0.3f).ToLinear();
|
||||||
|
|
||||||
|
leftBox.ColourInfo = ColourInfo.GradientHorizontal(gradientLight, gradientDark);
|
||||||
|
rightBox.ColourInfo = ColourInfo.GradientHorizontal(gradientDark, gradientLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||||
|
{
|
||||||
|
if (beatIndex < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (effectPoint.KiaiMode ? beatIndex % 2 == 0 : beatIndex % (int)timingPoint.TimeSignature == 0)
|
||||||
|
flash(leftBox, timingPoint.BeatLength, effectPoint.KiaiMode, amplitudes);
|
||||||
|
if (effectPoint.KiaiMode ? beatIndex % 2 == 1 : beatIndex % (int)timingPoint.TimeSignature == 0)
|
||||||
|
flash(rightBox, timingPoint.BeatLength, effectPoint.KiaiMode, amplitudes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flash(Drawable d, double beatLength, bool kiai, TrackAmplitudes amplitudes)
|
||||||
|
{
|
||||||
|
d.FadeTo(Math.Max(0, ((d.Equals(leftBox) ? amplitudes.LeftChannel : amplitudes.RightChannel) - amplitude_dead_zone) / (kiai ? kiai_multiplier : alpha_multiplier)), box_fade_in_time);
|
||||||
|
using (d.BeginDelayedSequence(box_fade_in_time))
|
||||||
|
d.FadeOut(beatLength, EasingTypes.In);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,13 +5,17 @@ using System;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
@ -20,19 +24,23 @@ namespace osu.Game.Screens.Menu
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// osu! logo and its attachments (pulsing, visualiser etc.)
|
/// osu! logo and its attachments (pulsing, visualiser etc.)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OsuLogo : Container
|
public class OsuLogo : BeatSyncedContainer
|
||||||
{
|
{
|
||||||
public readonly Color4 OsuPink = OsuColour.FromHex(@"e967a1");
|
public readonly Color4 OsuPink = OsuColour.FromHex(@"e967a1");
|
||||||
|
|
||||||
private readonly Sprite logo;
|
private readonly Sprite logo;
|
||||||
private readonly CircularContainer logoContainer;
|
private readonly CircularContainer logoContainer;
|
||||||
private readonly Container logoBounceContainer;
|
private readonly Container logoBounceContainer;
|
||||||
|
private readonly Container logoBeatContainer;
|
||||||
|
private readonly Container logoAmplitudeContainer;
|
||||||
private readonly Container logoHoverContainer;
|
private readonly Container logoHoverContainer;
|
||||||
|
|
||||||
private SampleChannel sampleClick;
|
private SampleChannel sampleClick;
|
||||||
|
|
||||||
private readonly Container colourAndTriangles;
|
private readonly Container colourAndTriangles;
|
||||||
|
|
||||||
|
private readonly Triangles triangles;
|
||||||
|
|
||||||
public Action Action;
|
public Action Action;
|
||||||
|
|
||||||
public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * logoHoverContainer.Scale.X * 0.74f;
|
public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * logoHoverContainer.Scale.X * 0.74f;
|
||||||
@ -67,8 +75,12 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
private const float default_size = 480;
|
private const float default_size = 480;
|
||||||
|
|
||||||
|
private const double beat_in_time = 60;
|
||||||
|
|
||||||
public OsuLogo()
|
public OsuLogo()
|
||||||
{
|
{
|
||||||
|
EarlyActivationMilliseconds = beat_in_time;
|
||||||
|
|
||||||
Size = new Vector2(default_size);
|
Size = new Vector2(default_size);
|
||||||
|
|
||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
@ -78,67 +90,16 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
logoBounceContainer = new Container
|
logoHoverContainer = new Container
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
logoHoverContainer = new Container
|
logoBounceContainer = new Container
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new BufferedContainer
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
logoContainer = new CircularContainer
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Scale = new Vector2(0.88f),
|
|
||||||
Masking = true,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
colourAndTriangles = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Colour = OsuPink,
|
|
||||||
},
|
|
||||||
new Triangles
|
|
||||||
{
|
|
||||||
TriangleScale = 4,
|
|
||||||
ColourLight = OsuColour.FromHex(@"ff7db7"),
|
|
||||||
ColourDark = OsuColour.FromHex(@"de5b95"),
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
flashLayer = new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
BlendingMode = BlendingMode.Additive,
|
|
||||||
Colour = Color4.White,
|
|
||||||
Alpha = 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
logo = new Sprite
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
rippleContainer = new Container
|
rippleContainer = new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -151,36 +112,101 @@ namespace osu.Game.Screens.Menu
|
|||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
BlendingMode = BlendingMode.Additive,
|
BlendingMode = BlendingMode.Additive,
|
||||||
Alpha = 0.15f
|
Alpha = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
impactContainer = new CircularContainer
|
logoAmplitudeContainer = new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
AutoSizeAxes = Axes.Both,
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Alpha = 0,
|
|
||||||
BorderColour = Color4.White,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
BorderThickness = 10,
|
|
||||||
Masking = true,
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
logoBeatContainer = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
AlwaysPresent = true,
|
Children = new Drawable[]
|
||||||
Alpha = 0,
|
{
|
||||||
|
new BufferedContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
logoContainer = new CircularContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Scale = new Vector2(0.88f),
|
||||||
|
Masking = true,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
colourAndTriangles = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuPink,
|
||||||
|
},
|
||||||
|
triangles = new Triangles
|
||||||
|
{
|
||||||
|
TriangleScale = 4,
|
||||||
|
ColourLight = OsuColour.FromHex(@"ff7db7"),
|
||||||
|
ColourDark = OsuColour.FromHex(@"de5b95"),
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
flashLayer = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
BlendingMode = BlendingMode.Additive,
|
||||||
|
Colour = Color4.White,
|
||||||
|
Alpha = 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logo = new Sprite
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
impactContainer = new CircularContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Alpha = 0,
|
||||||
|
BorderColour = Color4.White,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
BorderThickness = 10,
|
||||||
|
Masking = true,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
AlwaysPresent = true,
|
||||||
|
Alpha = 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new MenuVisualisation
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
BlendingMode = BlendingMode.Additive,
|
||||||
|
Alpha = 0.2f,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
new MenuVisualisation
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
BlendingMode = BlendingMode.Additive,
|
|
||||||
Alpha = 0.2f,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,13 +223,56 @@ namespace osu.Game.Screens.Menu
|
|||||||
ripple.Texture = textures.Get(@"Menu/logo");
|
ripple.Texture = textures.Get(@"Menu/logo");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
private int lastBeatIndex;
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
ripple.ScaleTo(ripple.Scale * 1.1f, 500);
|
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||||
ripple.FadeOut(500);
|
{
|
||||||
ripple.Loop(300);
|
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||||
|
|
||||||
|
lastBeatIndex = beatIndex;
|
||||||
|
|
||||||
|
var beatLength = timingPoint.BeatLength;
|
||||||
|
|
||||||
|
float amplitudeAdjust = Math.Min(1, 0.4f + amplitudes.Maximum);
|
||||||
|
|
||||||
|
if (beatIndex < 0) return;
|
||||||
|
|
||||||
|
logoBeatContainer.ScaleTo(1 - 0.02f * amplitudeAdjust, beat_in_time, EasingTypes.Out);
|
||||||
|
using (logoBeatContainer.BeginDelayedSequence(beat_in_time))
|
||||||
|
logoBeatContainer.ScaleTo(1, beatLength * 2, EasingTypes.OutQuint);
|
||||||
|
|
||||||
|
ripple.ClearTransforms();
|
||||||
|
|
||||||
|
ripple.ScaleTo(logoAmplitudeContainer.Scale);
|
||||||
|
ripple.Alpha = 0.15f * amplitudeAdjust;
|
||||||
|
|
||||||
|
ripple.ScaleTo(logoAmplitudeContainer.Scale * (1 + 0.04f * amplitudeAdjust), beatLength, EasingTypes.OutQuint);
|
||||||
|
ripple.FadeOut(beatLength, EasingTypes.OutQuint);
|
||||||
|
|
||||||
|
if (effectPoint.KiaiMode && flashLayer.Alpha < 0.4f)
|
||||||
|
{
|
||||||
|
flashLayer.ClearTransforms();
|
||||||
|
|
||||||
|
flashLayer.FadeTo(0.2f * amplitudeAdjust, beat_in_time, EasingTypes.Out);
|
||||||
|
using (flashLayer.BeginDelayedSequence(beat_in_time))
|
||||||
|
flashLayer.FadeOut(beatLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
const float scale_adjust_cutoff = 0.4f;
|
||||||
|
const float velocity_adjust_cutoff = 0.98f;
|
||||||
|
|
||||||
|
var maxAmplitude = lastBeatIndex >= 0 ? Beatmap.Value?.Track?.CurrentAmplitudes.Maximum ?? 0 : 0;
|
||||||
|
logoAmplitudeContainer.ScaleTo(1 - Math.Max(0, maxAmplitude - scale_adjust_cutoff) * 0.04f, 75, EasingTypes.OutQuint);
|
||||||
|
|
||||||
|
if (maxAmplitude > velocity_adjust_cutoff)
|
||||||
|
triangles.Velocity = 1 + Math.Max(0, maxAmplitude - velocity_adjust_cutoff) * 50;
|
||||||
|
else
|
||||||
|
triangles.Velocity = (float)Interpolation.Damp(triangles.Velocity, 1, 0.995f, Time.Elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
@ -254,4 +323,4 @@ namespace osu.Game.Screens.Menu
|
|||||||
impactContainer.ScaleTo(1.12f, 250);
|
impactContainer.ScaleTo(1.12f, 250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
259
osu.Game/Screens/Multiplayer/DrawableRoom.cs
Normal file
259
osu.Game/Screens/Multiplayer/DrawableRoom.cs
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
// 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.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Multiplayer
|
||||||
|
{
|
||||||
|
public class DrawableRoom : ClickableContainer
|
||||||
|
{
|
||||||
|
private const float content_padding = 5;
|
||||||
|
private const float height = 90;
|
||||||
|
|
||||||
|
private readonly Box sideStrip;
|
||||||
|
private readonly UpdateableAvatar avatar;
|
||||||
|
private readonly OsuSpriteText name;
|
||||||
|
private readonly Container flagContainer;
|
||||||
|
private readonly OsuSpriteText host;
|
||||||
|
private readonly OsuSpriteText rankBounds;
|
||||||
|
private readonly OsuSpriteText status;
|
||||||
|
private readonly FillFlowContainer<OsuSpriteText> beatmapInfoFlow;
|
||||||
|
private readonly OsuSpriteText beatmapTitle;
|
||||||
|
private readonly OsuSpriteText beatmapDash;
|
||||||
|
private readonly OsuSpriteText beatmapArtist;
|
||||||
|
|
||||||
|
private OsuColour colours;
|
||||||
|
private LocalisationEngine localisation;
|
||||||
|
|
||||||
|
public readonly Room Room;
|
||||||
|
|
||||||
|
public DrawableRoom(Room room)
|
||||||
|
{
|
||||||
|
Room = room;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
Height = height;
|
||||||
|
CornerRadius = 5;
|
||||||
|
Masking = true;
|
||||||
|
EdgeEffect = new EdgeEffect
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = Color4.Black.Opacity(40),
|
||||||
|
Radius = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.Gray(34),
|
||||||
|
},
|
||||||
|
sideStrip = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Width = content_padding,
|
||||||
|
},
|
||||||
|
avatar = new UpdateableAvatar
|
||||||
|
{
|
||||||
|
Size = new Vector2(Height - content_padding* 2),
|
||||||
|
Masking = true,
|
||||||
|
CornerRadius = 5f,
|
||||||
|
Margin = new MarginPadding { Left = content_padding * 2, Top = content_padding },
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Top = content_padding, Bottom = content_padding, Left = Height + content_padding * 2, Right = content_padding },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(5f),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
name = new OsuSpriteText
|
||||||
|
{
|
||||||
|
TextSize = 18,
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 20f,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Spacing = new Vector2(5f, 0f),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
flagContainer = new Container
|
||||||
|
{
|
||||||
|
Width = 30f,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
Width = 40f,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = "hosted by",
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
TextSize = 14,
|
||||||
|
},
|
||||||
|
host = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-BoldItalic",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rankBounds = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreRight,
|
||||||
|
Origin = Anchor.CentreRight,
|
||||||
|
Text = "#0 - #0",
|
||||||
|
TextSize = 14,
|
||||||
|
Margin = new MarginPadding { Right = 10 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Margin = new MarginPadding { Bottom = content_padding },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
status = new OsuSpriteText
|
||||||
|
{
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-Bold",
|
||||||
|
},
|
||||||
|
beatmapInfoFlow = new FillFlowContainer<OsuSpriteText>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
beatmapTitle = new OsuSpriteText
|
||||||
|
{
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-BoldItalic",
|
||||||
|
},
|
||||||
|
beatmapDash = new OsuSpriteText
|
||||||
|
{
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-RegularItalic",
|
||||||
|
},
|
||||||
|
beatmapArtist = new OsuSpriteText
|
||||||
|
{
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-RegularItalic",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Room.Name.ValueChanged += displayName;
|
||||||
|
Room.Host.ValueChanged += displayUser;
|
||||||
|
Room.Status.ValueChanged += displayStatus;
|
||||||
|
Room.Beatmap.ValueChanged += displayBeatmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours, LocalisationEngine localisation)
|
||||||
|
{
|
||||||
|
this.localisation = localisation;
|
||||||
|
this.colours = colours;
|
||||||
|
|
||||||
|
beatmapInfoFlow.Colour = rankBounds.Colour = colours.Gray9;
|
||||||
|
host.Colour = colours.Blue;
|
||||||
|
|
||||||
|
displayStatus(Room.Status.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayName(string value)
|
||||||
|
{
|
||||||
|
name.Text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayUser(User value)
|
||||||
|
{
|
||||||
|
avatar.User = value;
|
||||||
|
host.Text = value.Username;
|
||||||
|
flagContainer.Children = new[] { new DrawableFlag(value.Country?.FlagName ?? @"__") { RelativeSizeAxes = Axes.Both } };
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayStatus(RoomStatus value)
|
||||||
|
{
|
||||||
|
if (value == null) return;
|
||||||
|
status.Text = value.Message;
|
||||||
|
|
||||||
|
foreach (Drawable d in new Drawable[] { sideStrip, status })
|
||||||
|
d.FadeColour(value.GetAppropriateColour(colours), 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayBeatmap(BeatmapMetadata value)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
beatmapTitle.Current = localisation.GetUnicodePreference(value.TitleUnicode, value.Title);
|
||||||
|
beatmapDash.Text = @" - ";
|
||||||
|
beatmapArtist.Current = localisation.GetUnicodePreference(value.ArtistUnicode, value.Artist);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
beatmapTitle.Current = null;
|
||||||
|
beatmapArtist.Current = null;
|
||||||
|
|
||||||
|
beatmapTitle.Text = @"Changing map";
|
||||||
|
beatmapDash.Text = string.Empty;
|
||||||
|
beatmapArtist.Text = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
Room.Name.ValueChanged -= displayName;
|
||||||
|
Room.Host.ValueChanged -= displayUser;
|
||||||
|
Room.Status.ValueChanged -= displayStatus;
|
||||||
|
Room.Beatmap.ValueChanged -= displayBeatmap;
|
||||||
|
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,6 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -12,6 +11,7 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.HUD
|
namespace osu.Game.Screens.Play.HUD
|
||||||
{
|
{
|
||||||
@ -27,7 +27,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
iconsContainer = new IconFlow
|
iconsContainer = new ReverseDepthFillFlowContainer<ModIcon>
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
@ -93,12 +93,5 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
contract();
|
contract();
|
||||||
base.OnHoverLost(state);
|
base.OnHoverLost(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IconFlow : FillFlowContainer<ModIcon>
|
|
||||||
{
|
|
||||||
// just reverses the depth of flow contents.
|
|
||||||
protected override IComparer<Drawable> DepthComparer => new ReverseCreationOrderDepthComparer();
|
|
||||||
protected override IEnumerable<ModIcon> FlowingChildren => base.FlowingChildren.Reverse();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,8 +170,8 @@ namespace osu.Game.Screens.Select
|
|||||||
List<BeatmapGroup> visibleGroups = groups.Where(selectGroup => selectGroup.State != BeatmapGroupState.Hidden).ToList();
|
List<BeatmapGroup> visibleGroups = groups.Where(selectGroup => selectGroup.State != BeatmapGroupState.Hidden).ToList();
|
||||||
if (visibleGroups.Count < 1)
|
if (visibleGroups.Count < 1)
|
||||||
return;
|
return;
|
||||||
BeatmapGroup group = visibleGroups[RNG.Next(visibleGroups.Count)];
|
|
||||||
|
|
||||||
|
BeatmapGroup group = visibleGroups[RNG.Next(visibleGroups.Count)];
|
||||||
BeatmapPanel panel = group.BeatmapPanels[RNG.Next(group.BeatmapPanels.Count)];
|
BeatmapPanel panel = group.BeatmapPanels[RNG.Next(group.BeatmapPanels.Count)];
|
||||||
|
|
||||||
selectGroup(group, panel);
|
selectGroup(group, panel);
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -12,6 +10,7 @@ using osu.Game.Graphics;
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Options
|
namespace osu.Game.Screens.Select.Options
|
||||||
{
|
{
|
||||||
@ -71,7 +70,7 @@ namespace osu.Game.Screens.Select.Options
|
|||||||
Scale = new Vector2(1, 0),
|
Scale = new Vector2(1, 0),
|
||||||
Colour = Color4.Black.Opacity(0.5f),
|
Colour = Color4.Black.Opacity(0.5f),
|
||||||
},
|
},
|
||||||
buttonsContainer = new ButtonFlow
|
buttonsContainer = new ReverseDepthFillFlowContainer<BeatmapOptionsButton>
|
||||||
{
|
{
|
||||||
Height = height,
|
Height = height,
|
||||||
RelativePositionAxes = Axes.X,
|
RelativePositionAxes = Axes.X,
|
||||||
@ -109,16 +108,5 @@ namespace osu.Game.Screens.Select.Options
|
|||||||
HotKey = hotkey
|
HotKey = hotkey
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ButtonFlow : FillFlowContainer<BeatmapOptionsButton>
|
|
||||||
{
|
|
||||||
protected override IComparer<Drawable> DepthComparer => new ReverseCreationOrderDepthComparer();
|
|
||||||
protected override IEnumerable<BeatmapOptionsButton> FlowingChildren => base.FlowingChildren.Reverse();
|
|
||||||
|
|
||||||
public ButtonFlow()
|
|
||||||
{
|
|
||||||
Direction = FillDirection.Horizontal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,11 +316,12 @@ namespace osu.Game.Screens.Select
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void selectionChanged(BeatmapInfo beatmap)
|
private void selectionChanged(BeatmapInfo beatmap)
|
||||||
{
|
{
|
||||||
bool beatmapSetChange = false;
|
selectionChangedDebounce?.Cancel();
|
||||||
|
|
||||||
if (beatmap.Equals(Beatmap?.BeatmapInfo))
|
if (beatmap.Equals(Beatmap?.BeatmapInfo))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool beatmapSetChange = false;
|
||||||
if (beatmap.BeatmapSetInfoID == selectionChangeNoBounce?.BeatmapSetInfoID)
|
if (beatmap.BeatmapSetInfoID == selectionChangeNoBounce?.BeatmapSetInfoID)
|
||||||
sampleChangeDifficulty.Play();
|
sampleChangeDifficulty.Play();
|
||||||
else
|
else
|
||||||
@ -331,7 +332,6 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
selectionChangeNoBounce = beatmap;
|
selectionChangeNoBounce = beatmap;
|
||||||
|
|
||||||
selectionChangedDebounce?.Cancel();
|
|
||||||
selectionChangedDebounce = Scheduler.AddDelayed(delegate
|
selectionChangedDebounce = Scheduler.AddDelayed(delegate
|
||||||
{
|
{
|
||||||
Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap);
|
Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
|
||||||
namespace osu.Game.Users
|
namespace osu.Game.Users
|
||||||
{
|
{
|
||||||
@ -19,6 +20,8 @@ namespace osu.Game.Users
|
|||||||
[JsonProperty(@"country")]
|
[JsonProperty(@"country")]
|
||||||
public Country Country;
|
public Country Country;
|
||||||
|
|
||||||
|
public Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
||||||
|
|
||||||
//public Team Team;
|
//public Team Team;
|
||||||
|
|
||||||
[JsonProperty(@"profile_colour")]
|
[JsonProperty(@"profile_colour")]
|
||||||
|
214
osu.Game/Users/UserPanel.cs
Normal file
214
osu.Game/Users/UserPanel.cs
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
// 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.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Users
|
||||||
|
{
|
||||||
|
public class UserPanel : Container
|
||||||
|
{
|
||||||
|
private const float height = 100;
|
||||||
|
private const float content_padding = 10;
|
||||||
|
private const float status_height = 30;
|
||||||
|
|
||||||
|
private OsuColour colours;
|
||||||
|
|
||||||
|
private readonly Container statusBar;
|
||||||
|
private readonly Box statusBg;
|
||||||
|
private readonly OsuSpriteText statusMessage;
|
||||||
|
|
||||||
|
public readonly Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
||||||
|
|
||||||
|
public UserPanel(User user)
|
||||||
|
{
|
||||||
|
Height = height - status_height;
|
||||||
|
Masking = true;
|
||||||
|
CornerRadius = 5;
|
||||||
|
EdgeEffect = new EdgeEffect
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
Radius = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new AsyncLoadWrapper(new CoverBackgroundSprite(user)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
FillMode = FillMode.Fill,
|
||||||
|
OnLoadComplete = d => d.FadeInFromZero(200),
|
||||||
|
}) { RelativeSizeAxes = Axes.Both },
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black.Opacity(0.7f),
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Padding = new MarginPadding { Top = content_padding, Left = content_padding, Right = content_padding },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new UpdateableAvatar
|
||||||
|
{
|
||||||
|
Size = new Vector2(height - status_height - content_padding * 2),
|
||||||
|
User = user,
|
||||||
|
Masking = true,
|
||||||
|
CornerRadius = 5,
|
||||||
|
EdgeEffect = new EdgeEffect
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
Radius = 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Left = height - status_height - content_padding },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = user.Username,
|
||||||
|
TextSize = 18,
|
||||||
|
Font = @"Exo2.0-SemiBoldItalic",
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
Height = 20f,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Spacing = new Vector2(5f, 0f),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new DrawableFlag(user.Country?.FlagName ?? @"__")
|
||||||
|
{
|
||||||
|
Width = 30f,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
Width = 40f,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
new CircularContainer
|
||||||
|
{
|
||||||
|
Width = 20f,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
statusBar = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Alpha = 0f,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
statusBg = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0.5f,
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Spacing = new Vector2(5f, 0f),
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new TextAwesome
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Icon = FontAwesome.fa_circle_o,
|
||||||
|
Shadow = true,
|
||||||
|
TextSize = 14,
|
||||||
|
},
|
||||||
|
statusMessage = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Font = @"Exo2.0-Semibold",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
this.colours = colours;
|
||||||
|
Status.ValueChanged += displayStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
Status.TriggerChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayStatus(UserStatus status)
|
||||||
|
{
|
||||||
|
const float transition_duration = 500;
|
||||||
|
|
||||||
|
if (status == null)
|
||||||
|
{
|
||||||
|
statusBar.ResizeHeightTo(0f, transition_duration, EasingTypes.OutQuint);
|
||||||
|
statusBar.FadeOut(transition_duration, EasingTypes.OutQuint);
|
||||||
|
ResizeHeightTo(height - status_height, transition_duration, EasingTypes.OutQuint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statusBar.ResizeHeightTo(status_height, transition_duration, EasingTypes.OutQuint);
|
||||||
|
statusBar.FadeIn(transition_duration, EasingTypes.OutQuint);
|
||||||
|
ResizeHeightTo(height, transition_duration, EasingTypes.OutQuint);
|
||||||
|
|
||||||
|
statusBg.FadeColour(status.GetAppropriateColour(colours), 500, EasingTypes.OutQuint);
|
||||||
|
statusMessage.Text = status.Message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CoverBackgroundSprite : Sprite
|
||||||
|
{
|
||||||
|
private readonly User user;
|
||||||
|
|
||||||
|
public CoverBackgroundSprite(User user)
|
||||||
|
{
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(user.CoverUrl))
|
||||||
|
Texture = textures.Get(user.CoverUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
osu.Game/Users/UserStatus.cs
Normal file
67
osu.Game/Users/UserStatus.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// 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.Game.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Users
|
||||||
|
{
|
||||||
|
public abstract class UserStatus
|
||||||
|
{
|
||||||
|
public abstract string Message { get; }
|
||||||
|
public abstract Color4 GetAppropriateColour(OsuColour colours);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class UserStatusAvailable : UserStatus
|
||||||
|
{
|
||||||
|
public override Color4 GetAppropriateColour(OsuColour colours) => colours.BlueDarker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class UserStatusBusy : UserStatus
|
||||||
|
{
|
||||||
|
public override Color4 GetAppropriateColour(OsuColour colours) => colours.YellowDark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStatusOffline : UserStatus
|
||||||
|
{
|
||||||
|
public override string Message => @"Offline";
|
||||||
|
public override Color4 GetAppropriateColour(OsuColour colours) => colours.Gray7;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStatusOnline : UserStatusAvailable
|
||||||
|
{
|
||||||
|
public override string Message => @"Online";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStatusSpectating : UserStatusAvailable
|
||||||
|
{
|
||||||
|
public override string Message => @"Spectating a game";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStatusInLobby : UserStatusAvailable
|
||||||
|
{
|
||||||
|
public override string Message => @"in Multiplayer Lobby";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStatusSoloGame : UserStatusBusy
|
||||||
|
{
|
||||||
|
public override string Message => @"Solo Game";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStatusMultiplayerGame: UserStatusBusy
|
||||||
|
{
|
||||||
|
public override string Message => @"Multiplaying";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStatusModding : UserStatus
|
||||||
|
{
|
||||||
|
public override string Message => @"Modding a map";
|
||||||
|
public override Color4 GetAppropriateColour(OsuColour colours) => colours.PurpleDark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStatusDoNotDisturb : UserStatus
|
||||||
|
{
|
||||||
|
public override string Message => @"Do not disturb";
|
||||||
|
public override Color4 GetAppropriateColour(OsuColour colours) => colours.RedDark;
|
||||||
|
}
|
||||||
|
}
|
@ -189,6 +189,7 @@
|
|||||||
<Compile Include="Database\RulesetDatabase.cs" />
|
<Compile Include="Database\RulesetDatabase.cs" />
|
||||||
<Compile Include="Rulesets\Scoring\Score.cs" />
|
<Compile Include="Rulesets\Scoring\Score.cs" />
|
||||||
<Compile Include="Rulesets\Scoring\ScoreProcessor.cs" />
|
<Compile Include="Rulesets\Scoring\ScoreProcessor.cs" />
|
||||||
|
<Compile Include="Screens\Menu\MenuSideFlashes.cs" />
|
||||||
<Compile Include="Screens\Play\HUD\HealthDisplay.cs" />
|
<Compile Include="Screens\Play\HUD\HealthDisplay.cs" />
|
||||||
<Compile Include="Screens\Play\HUDOverlay.cs" />
|
<Compile Include="Screens\Play\HUDOverlay.cs" />
|
||||||
<Compile Include="Screens\Play\HUD\StandardHealthDisplay.cs" />
|
<Compile Include="Screens\Play\HUD\StandardHealthDisplay.cs" />
|
||||||
@ -431,6 +432,24 @@
|
|||||||
<Compile Include="Overlays\Music\PlaylistOverlay.cs" />
|
<Compile Include="Overlays\Music\PlaylistOverlay.cs" />
|
||||||
<Compile Include="Rulesets\Replays\IAutoGenerator.cs" />
|
<Compile Include="Rulesets\Replays\IAutoGenerator.cs" />
|
||||||
<Compile Include="Rulesets\Replays\AutoGenerator.cs" />
|
<Compile Include="Rulesets\Replays\AutoGenerator.cs" />
|
||||||
|
<Compile Include="Screens\Multiplayer\DrawableRoom.cs" />
|
||||||
|
<Compile Include="Online\Multiplayer\Room.cs" />
|
||||||
|
<Compile Include="Online\Multiplayer\RoomStatus.cs" />
|
||||||
|
<Compile Include="Users\UserPanel.cs" />
|
||||||
|
<Compile Include="Users\UserStatus.cs" />
|
||||||
|
<Compile Include="Overlays\DirectOverlay.cs" />
|
||||||
|
<Compile Include="Overlays\Direct\FilterControl.cs" />
|
||||||
|
<Compile Include="Overlays\Direct\Header.cs" />
|
||||||
|
<Compile Include="Overlays\Direct\SortTabControl.cs" />
|
||||||
|
<Compile Include="Graphics\UserInterface\OsuEnumDropdown.cs" />
|
||||||
|
<Compile Include="Overlays\Direct\DirectPanel.cs" />
|
||||||
|
<Compile Include="Overlays\Direct\DirectGridPanel.cs" />
|
||||||
|
<Compile Include="Overlays\Direct\DirectListPanel.cs" />
|
||||||
|
<Compile Include="Database\OnlineWorkingBeatmap.cs" />
|
||||||
|
<Compile Include="Database\BeatmapOnlineInfo.cs" />
|
||||||
|
<Compile Include="Overlays\Direct\SlimEnumDropdown.cs" />
|
||||||
|
<Compile Include="Graphics\Containers\ReverseDepthFillFlowContainer.cs" />
|
||||||
|
<Compile Include="Database\RankStatus.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
|
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user