1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 22:07:28 +08:00

Merge branch 'master' into taiko_bash_drawable

This commit is contained in:
Dean Herbert 2017-03-23 10:25:46 +09:00 committed by GitHub
commit 3544d9844d
66 changed files with 1737 additions and 706 deletions

@ -1 +1 @@
Subproject commit e6394035d443d4498b71e845e5763dd3faf98c7c Subproject commit 42ec8a62fb697f1d967a927549dc51336cd66968

View File

@ -0,0 +1,24 @@
// 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.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
namespace osu.Desktop.VisualTests.Beatmaps
{
public class TestWorkingBeatmap : WorkingBeatmap
{
public TestWorkingBeatmap(Beatmap beatmap)
: base(beatmap.BeatmapInfo, beatmap.BeatmapInfo.BeatmapSet)
{
this.beatmap = beatmap;
}
private Beatmap beatmap;
protected override Beatmap GetBeatmap() => beatmap;
protected override Texture GetBackground() => null;
protected override Track GetTrack() => null;
}
}

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using osu.Framework.Screens.Testing; using osu.Framework.Screens.Testing;
using osu.Game.Screens.Tournament; using osu.Game.Screens.Tournament;
using osu.Game.Screens.Tournament.Teams; using osu.Game.Screens.Tournament.Teams;
using osu.Game.Users;
namespace osu.Desktop.VisualTests.Tests namespace osu.Desktop.VisualTests.Tests
{ {
@ -24,57 +25,57 @@ namespace osu.Desktop.VisualTests.Tests
private class TestTeamList : ITeamList private class TestTeamList : ITeamList
{ {
public IEnumerable<Team> Teams { get; } = new[] public IEnumerable<Country> Teams { get; } = new[]
{ {
new Team new Country
{ {
FlagName = "GB", FlagName = "GB",
FullName = "United Kingdom", FullName = "United Kingdom",
Acronym = "UK" Acronym = "UK"
}, },
new Team new Country
{ {
FlagName = "FR", FlagName = "FR",
FullName = "France", FullName = "France",
Acronym = "FRA" Acronym = "FRA"
}, },
new Team new Country
{ {
FlagName = "CN", FlagName = "CN",
FullName = "China", FullName = "China",
Acronym = "CHN" Acronym = "CHN"
}, },
new Team new Country
{ {
FlagName = "AU", FlagName = "AU",
FullName = "Australia", FullName = "Australia",
Acronym = "AUS" Acronym = "AUS"
}, },
new Team new Country
{ {
FlagName = "JP", FlagName = "JP",
FullName = "Japan", FullName = "Japan",
Acronym = "JPN" Acronym = "JPN"
}, },
new Team new Country
{ {
FlagName = "RO", FlagName = "RO",
FullName = "Romania", FullName = "Romania",
Acronym = "ROM" Acronym = "ROM"
}, },
new Team new Country
{ {
FlagName = "IT", FlagName = "IT",
FullName = "Italy", FullName = "Italy",
Acronym = "PIZZA" Acronym = "PIZZA"
}, },
new Team new Country
{ {
FlagName = "VE", FlagName = "VE",
FullName = "Venezuela", FullName = "Venezuela",
Acronym = "VNZ" Acronym = "VNZ"
}, },
new Team new Country
{ {
FlagName = "US", FlagName = "US",
FullName = "United States of America", FullName = "United States of America",

View File

@ -8,7 +8,6 @@ using osu.Framework.MathUtils;
using osu.Framework.Screens.Testing; using osu.Framework.Screens.Testing;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.IO;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Modes.Catch.UI; using osu.Game.Modes.Catch.UI;
using osu.Game.Modes.Mania.UI; using osu.Game.Modes.Mania.UI;
@ -17,6 +16,7 @@ using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.UI; using osu.Game.Modes.Osu.UI;
using osu.Game.Modes.Taiko.UI; using osu.Game.Modes.Taiko.UI;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Desktop.VisualTests.Beatmaps;
namespace osu.Desktop.VisualTests.Tests namespace osu.Desktop.VisualTests.Tests
{ {
@ -95,16 +95,5 @@ namespace osu.Desktop.VisualTests.Tests
} }
}); });
} }
private class TestWorkingBeatmap : WorkingBeatmap
{
public TestWorkingBeatmap(Beatmap beatmap)
: base(beatmap.BeatmapInfo, beatmap.BeatmapInfo.BeatmapSet)
{
Beatmap = beatmap;
}
protected override ArchiveReader GetReader() => null;
}
} }
} }

View File

@ -0,0 +1,225 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Screens.Testing;
using osu.Game.Modes;
using osu.Game.Modes.Mods;
using osu.Game.Modes.Osu.Mods;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Users;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseLeaderboard : TestCase
{
public override string Description => @"From song select";
private Leaderboard leaderboard;
private void newScores()
{
var scores = new[]
{
new Score
{
Rank = ScoreRank.XH,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 6602580,
Username = @"waaiiru",
Country = new Country
{
FullName = @"Spain",
FlagName = @"ES",
},
},
},
new Score
{
Rank = ScoreRank.X,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 4608074,
Username = @"Skycries",
Country = new Country
{
FullName = @"Brazil",
FlagName = @"BR",
},
},
},
new Score
{
Rank = ScoreRank.SH,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 1014222,
Username = @"eLy",
Country = new Country
{
FullName = @"Japan",
FlagName = @"JP",
},
},
},
new Score
{
Rank = ScoreRank.S,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 1541390,
Username = @"Toukai",
Country = new Country
{
FullName = @"Canada",
FlagName = @"CA",
},
},
},
new Score
{
Rank = ScoreRank.A,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 2243452,
Username = @"Satoruu",
Country = new Country
{
FullName = @"Venezuela",
FlagName = @"VE",
},
},
},
new Score
{
Rank = ScoreRank.B,
Accuracy = 98.26,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 2705430,
Username = @"Mooha",
Country = new Country
{
FullName = @"France",
FlagName = @"FR",
},
},
},
new Score
{
Rank = ScoreRank.C,
Accuracy = 96.54,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 7151382,
Username = @"Mayuri Hana",
Country = new Country
{
FullName = @"Thailand",
FlagName = @"TH",
},
},
},
new Score
{
Rank = ScoreRank.F,
Accuracy = 60.25,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 2051389,
Username = @"FunOrange",
Country = new Country
{
FullName = @"Canada",
FlagName = @"CA",
},
},
},
new Score
{
Rank = ScoreRank.F,
Accuracy = 51.40,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 6169483,
Username = @"-Hebel-",
Country = new Country
{
FullName = @"Mexico",
FlagName = @"MX",
},
},
},
new Score
{
Rank = ScoreRank.F,
Accuracy = 42.22,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 6702666,
Username = @"prhtnsm",
Country = new Country
{
FullName = @"Germany",
FlagName = @"DE",
},
},
},
};
leaderboard.Scores = scores;
}
public override void Reset()
{
base.Reset();
Add(leaderboard = new Leaderboard
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(550f, 450f),
});
AddButton(@"New Scores", newScores);
newScores();
}
}
}

View File

@ -8,13 +8,13 @@ using osu.Framework.Screens.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using OpenTK; using OpenTK;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps.IO;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Modes; using osu.Game.Modes;
using osu.Game.Modes.Objects; using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Desktop.VisualTests.Beatmaps;
namespace osu.Desktop.VisualTests.Tests namespace osu.Desktop.VisualTests.Tests
{ {
@ -23,7 +23,6 @@ namespace osu.Desktop.VisualTests.Tests
protected Player Player; protected Player Player;
private BeatmapDatabase db; private BeatmapDatabase db;
public override string Description => @"Showing everything to play the game."; public override string Description => @"Showing everything to play the game.";
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -97,16 +96,5 @@ namespace osu.Desktop.VisualTests.Tests
Beatmap = beatmap Beatmap = beatmap
}; };
} }
private class TestWorkingBeatmap : WorkingBeatmap
{
public TestWorkingBeatmap(Beatmap beatmap)
: base(beatmap.BeatmapInfo, beatmap.BeatmapInfo.BeatmapSet)
{
Beatmap = beatmap;
}
protected override ArchiveReader GetReader() => null;
}
} }
} }

View File

@ -204,9 +204,14 @@
<Compile Include="Tests\TestCaseModSelectOverlay.cs" /> <Compile Include="Tests\TestCaseModSelectOverlay.cs" />
<Compile Include="Tests\TestCaseDialogOverlay.cs" /> <Compile Include="Tests\TestCaseDialogOverlay.cs" />
<Compile Include="Tests\TestCaseBeatmapOptionsOverlay.cs" /> <Compile Include="Tests\TestCaseBeatmapOptionsOverlay.cs" />
<Compile Include="Tests\TestCaseLeaderboard.cs" />
<Compile Include="Beatmaps\TestWorkingBeatmap.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<ItemGroup /> <ItemGroup />
<ItemGroup>
<Folder Include="Beatmaps\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -111,8 +111,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
protected override void UpdateState(ArmedState state) protected override void UpdateState(ArmedState state)
{ {
if (!IsLoaded) return;
base.UpdateState(state); base.UpdateState(state);
ApproachCircle.FadeOut(); ApproachCircle.FadeOut();

View File

@ -22,8 +22,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
protected override void UpdateState(ArmedState state) protected override void UpdateState(ArmedState state)
{ {
if (!IsLoaded) return;
Flush(); Flush();
UpdateInitialState(); UpdateInitialState();

View File

@ -95,8 +95,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
protected override void UpdateState(ArmedState state) protected override void UpdateState(ArmedState state)
{ {
if (!IsLoaded) return;
base.UpdateState(state); base.UpdateState(state);
switch (state) switch (state)

View File

@ -134,8 +134,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
protected override void UpdateState(ArmedState state) protected override void UpdateState(ArmedState state)
{ {
if (!IsLoaded) return;
base.UpdateState(state); base.UpdateState(state);
Delay(spinner.Duration, true); Delay(spinner.Duration, true);

View File

@ -29,6 +29,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
{ {
new CircularContainer new CircularContainer
{ {
Masking = true,
Origin = Anchor.Centre,
EdgeEffect = new EdgeEffect EdgeEffect = new EdgeEffect
{ {
Type = EdgeEffectType.Glow, Type = EdgeEffectType.Glow,

View File

@ -33,6 +33,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
completeColour = colours.YellowLight.Opacity(0.8f); completeColour = colours.YellowLight.Opacity(0.8f);
Masking = true;
} }
private class SpinnerBorder : Container private class SpinnerBorder : Container
@ -61,6 +62,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
{ {
Colour = Color4.White, Colour = Color4.White,
RelativePositionAxes = Axes.Both, RelativePositionAxes = Axes.Both,
Masking = true,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Size = new Vector2(1 / ScreenSpaceDrawQuad.Width * 2000), Size = new Vector2(1 / ScreenSpaceDrawQuad.Width * 2000),
Children = new[] Children = new[]

View File

@ -4,14 +4,11 @@
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Modes; using osu.Game.Modes;
using osu.Game.Modes.Mods; using osu.Game.Modes.Mods;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
@ -27,14 +24,12 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public PlayMode? PreferredPlayMode; public PlayMode? PreferredPlayMode;
public PlayMode PlayMode => beatmap?.BeatmapInfo?.Mode > PlayMode.Osu ? beatmap.BeatmapInfo.Mode : PreferredPlayMode ?? PlayMode.Osu; public PlayMode PlayMode => Beatmap?.BeatmapInfo?.Mode > PlayMode.Osu ? Beatmap.BeatmapInfo.Mode : PreferredPlayMode ?? PlayMode.Osu;
public readonly Bindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>(); public readonly Bindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>();
public readonly bool WithStoryboard; public readonly bool WithStoryboard;
protected abstract ArchiveReader GetReader();
protected WorkingBeatmap(BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false) protected WorkingBeatmap(BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false)
{ {
BeatmapInfo = beatmapInfo; BeatmapInfo = beatmapInfo;
@ -42,31 +37,10 @@ namespace osu.Game.Beatmaps
WithStoryboard = withStoryboard; WithStoryboard = withStoryboard;
} }
private Texture background; protected abstract Beatmap GetBeatmap();
private object backgroundLock = new object(); protected abstract Texture GetBackground();
public Texture Background protected abstract Track GetTrack();
{
get
{
lock (backgroundLock)
{
if (background != null) return background;
if (BeatmapInfo?.Metadata?.BackgroundFile == null) return null;
try
{
using (var reader = GetReader())
background = new TextureStore(new RawTextureLoaderStore(reader), false).Get(BeatmapInfo.Metadata.BackgroundFile);
}
catch { }
return background;
}
}
set { lock (backgroundLock) background = value; }
}
private Beatmap beatmap; private Beatmap beatmap;
private object beatmapLock = new object(); private object beatmapLock = new object();
public Beatmap Beatmap public Beatmap Beatmap
@ -75,33 +49,24 @@ namespace osu.Game.Beatmaps
{ {
lock (beatmapLock) lock (beatmapLock)
{ {
if (beatmap != null) return beatmap; return beatmap ?? (beatmap = GetBeatmap());
}
try }
{ }
using (var reader = GetReader())
{ private object backgroundLock = new object();
BeatmapDecoder decoder; private Texture background;
using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path))) public Texture Background
{ {
decoder = BeatmapDecoder.GetDecoder(stream); get
beatmap = decoder?.Decode(stream); {
} lock (backgroundLock)
{
if (WithStoryboard && beatmap != null && BeatmapSetInfo.StoryboardFile != null) return background ?? (background = GetBackground());
using (var stream = new StreamReader(reader.GetStream(BeatmapSetInfo.StoryboardFile)))
decoder?.Decode(stream, beatmap);
}
}
catch { }
return beatmap;
} }
} }
set { lock (beatmapLock) beatmap = value; }
} }
private ArchiveReader trackReader;
private Track track; private Track track;
private object trackLock = new object(); private object trackLock = new object();
public Track Track public Track Track
@ -110,48 +75,25 @@ namespace osu.Game.Beatmaps
{ {
lock (trackLock) lock (trackLock)
{ {
if (track != null) return track; return track ?? (track = GetTrack());
try
{
//store a reference to the reader as we may continue accessing the stream in the background.
trackReader = GetReader();
var trackData = trackReader?.GetStream(BeatmapInfo.Metadata.AudioFile);
if (trackData != null)
track = new TrackBass(trackData);
}
catch { }
return track;
} }
} }
set { lock (trackLock) track = value; }
} }
public bool TrackLoaded => track != null; public bool TrackLoaded => track != null;
private bool isDisposed; public void TransferTo(WorkingBeatmap other)
protected virtual void Dispose(bool disposing)
{ {
if (!isDisposed) if (track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo))
{ other.track = track;
track?.Dispose();
background?.Dispose();
isDisposed = true;
}
} }
public void Dispose() public virtual void Dispose()
{ {
Dispose(true); track?.Dispose();
GC.SuppressFinalize(this); track = null;
} background?.Dispose();
background = null;
public void TransferTo(WorkingBeatmap working)
{
if (track != null && BeatmapInfo.AudioEquals(working.BeatmapInfo))
working.track = track;
} }
} }
} }

View File

@ -23,7 +23,8 @@ namespace osu.Game.Configuration
Set(OsuConfig.SavePassword, false); Set(OsuConfig.SavePassword, false);
Set(OsuConfig.SaveUsername, true); Set(OsuConfig.SaveUsername, true);
Set(OsuConfig.CursorSize, 1.0, 0.5f, 2); Set(OsuConfig.MenuCursorSize, 1.0, 0.5f, 2);
Set(OsuConfig.GameplayCursorSize, 1.0, 0.5f, 2);
Set(OsuConfig.DimLevel, 30, 0, 100); Set(OsuConfig.DimLevel, 30, 0, 100);
Set(OsuConfig.MouseDisableButtons, false); Set(OsuConfig.MouseDisableButtons, false);
@ -175,11 +176,11 @@ namespace osu.Game.Configuration
ConfineMouseMode.Fullscreen : ConfineMouseMode.Never).Disabled = true; ConfineMouseMode.Fullscreen : ConfineMouseMode.Never).Disabled = true;
GetBindable<bool>(OsuConfig.SavePassword).ValueChanged += delegate GetOriginalBindable<bool>(OsuConfig.SavePassword).ValueChanged += delegate
{ {
if (Get<bool>(OsuConfig.SavePassword)) Set(OsuConfig.SaveUsername, true); if (Get<bool>(OsuConfig.SavePassword)) Set(OsuConfig.SaveUsername, true);
}; };
GetBindable<bool>(OsuConfig.SaveUsername).ValueChanged += delegate GetOriginalBindable<bool>(OsuConfig.SaveUsername).ValueChanged += delegate
{ {
if (!Get<bool>(OsuConfig.SaveUsername)) Set(OsuConfig.SavePassword, false); if (!Get<bool>(OsuConfig.SaveUsername)) Set(OsuConfig.SavePassword, false);
}; };
@ -223,7 +224,8 @@ namespace osu.Game.Configuration
ComboFireHeight, ComboFireHeight,
ConfirmExit, ConfirmExit,
AutoSendNowPlaying, AutoSendNowPlaying,
CursorSize, MenuCursorSize,
GameplayCursorSize,
AutomaticCursorSizing, AutomaticCursorSizing,
DimLevel, DimLevel,
Display, Display,

View File

@ -342,18 +342,5 @@ namespace osu.Game.Database
} }
public bool Exists(BeatmapSetInfo beatmapSet) => storage.Exists(beatmapSet.Path); public bool Exists(BeatmapSetInfo beatmapSet) => storage.Exists(beatmapSet.Path);
private class DatabaseWorkingBeatmap : WorkingBeatmap
{
private readonly BeatmapDatabase database;
public DatabaseWorkingBeatmap(BeatmapDatabase database, BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false)
: base(beatmapInfo, beatmapSetInfo, withStoryboard)
{
this.database = database;
}
protected override ArchiveReader GetReader() => database?.GetReader(BeatmapSetInfo);
}
} }
} }

View File

@ -0,0 +1,73 @@
// 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.IO;
using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO;
namespace osu.Game.Database
{
internal class DatabaseWorkingBeatmap : WorkingBeatmap
{
private readonly BeatmapDatabase database;
public DatabaseWorkingBeatmap(BeatmapDatabase database, BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false)
: base(beatmapInfo, beatmapSetInfo, withStoryboard)
{
this.database = database;
}
private ArchiveReader getReader() => database?.GetReader(BeatmapSetInfo);
protected override Beatmap GetBeatmap()
{
try
{
Beatmap beatmap;
using (var reader = getReader())
{
BeatmapDecoder decoder;
using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path)))
{
decoder = BeatmapDecoder.GetDecoder(stream);
beatmap = decoder?.Decode(stream);
}
if (WithStoryboard && beatmap != null && BeatmapSetInfo.StoryboardFile != null)
using (var stream = new StreamReader(reader.GetStream(BeatmapSetInfo.StoryboardFile)))
decoder.Decode(stream, beatmap);
}
return beatmap;
}
catch { return null; }
}
protected override Texture GetBackground()
{
if (BeatmapInfo?.Metadata?.BackgroundFile == null)
return null;
try
{
using (var reader = getReader())
return new TextureStore(new RawTextureLoaderStore(reader), false).Get(BeatmapInfo.Metadata.BackgroundFile);
}
catch { return null; }
}
protected override Track GetTrack()
{
try
{
var trackData = getReader()?.GetStream(BeatmapInfo.Metadata.AudioFile);
return trackData == null ? null : new TrackBass(trackData);
}
catch { return null; }
}
}
}

View File

@ -54,8 +54,6 @@ namespace osu.Game.Graphics.Cursor
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config) private void load(OsuConfigManager config)
{ {
cursorScale = config.GetBindable<double>(OsuConfig.CursorSize);
Children = new Drawable[] Children = new Drawable[]
{ {
cursorContainer = new CircularContainer cursorContainer = new CircularContainer
@ -63,7 +61,6 @@ namespace osu.Game.Graphics.Cursor
Origin = Anchor.Centre, Origin = Anchor.Centre,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Scale = new Vector2((float)cursorScale),
Masking = true, Masking = true,
BorderThickness = Size.X / 6, BorderThickness = Size.X / 6,
BorderColour = Color4.White, BorderColour = Color4.White,
@ -119,7 +116,9 @@ namespace osu.Game.Graphics.Cursor
}, },
}; };
cursorScale = config.GetBindable<double>(OsuConfig.GameplayCursorSize);
cursorScale.ValueChanged += scaleChanged; cursorScale.ValueChanged += scaleChanged;
cursorScale.TriggerChange();
} }
private void scaleChanged(object sender, EventArgs e) private void scaleChanged(object sender, EventArgs e)

View File

@ -97,8 +97,6 @@ namespace osu.Game.Graphics.Cursor
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config, TextureStore textures, OsuColour colour) private void load(OsuConfigManager config, TextureStore textures, OsuColour colour)
{ {
cursorScale = config.GetBindable<double>(OsuConfig.CursorSize);
Children = new Drawable[] Children = new Drawable[]
{ {
cursorContainer = new Container cursorContainer = new Container
@ -122,7 +120,10 @@ namespace osu.Game.Graphics.Cursor
} }
} }
}; };
cursorScale = config.GetBindable<double>(OsuConfig.MenuCursorSize);
cursorScale.ValueChanged += scaleChanged; cursorScale.ValueChanged += scaleChanged;
cursorScale.TriggerChange();
} }
private void scaleChanged(object sender, EventArgs e) private void scaleChanged(object sender, EventArgs e)

View File

@ -30,6 +30,8 @@ namespace osu.Game.Graphics.UserInterface
BorderColour = Color4.White; BorderColour = Color4.White;
BorderThickness = border_width; BorderThickness = border_width;
Masking = true;
Children = new[] Children = new[]
{ {
fill = new Box fill = new Box

View File

@ -1,69 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.Sprites;
using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
namespace osu.Game.Graphics.UserInterface
{
public class OsuDropDownHeader : DropDownHeader
{
private SpriteText label;
protected override string Label
{
get { return label.Text; }
set { label.Text = value; }
}
private Color4? accentColour;
public virtual Color4 AccentColour
{
get { return accentColour.GetValueOrDefault(); }
set
{
accentColour = value;
BackgroundColourHover = value;
}
}
public OsuDropDownHeader()
{
Foreground.Padding = new MarginPadding(4);
AutoSizeAxes = Axes.None;
Margin = new MarginPadding { Bottom = 4 };
CornerRadius = 4;
Height = 40;
Foreground.Children = new Drawable[]
{
label = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
},
new TextAwesome
{
Icon = FontAwesome.fa_chevron_down,
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Margin = new MarginPadding { Right = 4 },
TextSize = 20
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = Color4.Black.Opacity(0.5f);
BackgroundColourHover = accentColour ?? colours.PinkDarker;
}
}
}

View File

@ -1,61 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using osu.Framework.Allocation;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface
{
public class OsuDropDownMenu<T> : DropDownMenu<T>
{
protected override DropDownHeader CreateHeader() => new OsuDropDownHeader { AccentColour = AccentColour };
private Color4? accentColour;
public virtual Color4 AccentColour
{
get { return accentColour.GetValueOrDefault(); }
set
{
accentColour = value;
if (Header != null)
((OsuDropDownHeader)Header).AccentColour = value;
foreach (var item in ItemList.OfType<OsuDropDownMenuItem<T>>())
item.AccentColour = value;
}
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == null)
AccentColour = colours.PinkDarker;
}
public OsuDropDownMenu()
{
ContentContainer.CornerRadius = 4;
ContentBackground.Colour = Color4.Black.Opacity(0.5f);
DropDownItemsContainer.Padding = new MarginPadding(5);
}
protected override void AnimateOpen() => ContentContainer.FadeIn(300, EasingTypes.OutQuint);
protected override void AnimateClose() => ContentContainer.FadeOut(300, EasingTypes.OutQuint);
protected override void UpdateContentHeight()
{
var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight;
ContentContainer.ResizeTo(new Vector2(1, State == DropDownMenuState.Opened ? actualHeight : 0), 300, EasingTypes.OutQuint);
}
protected override DropDownMenuItem<T> CreateDropDownItem(string key, T value) => new OsuDropDownMenuItem<T>(key, value) { AccentColour = AccentColour };
}
}

View File

@ -1,85 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.Sprites;
using OpenTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
public class OsuDropDownMenuItem<U> : DropDownMenuItem<U>
{
public OsuDropDownMenuItem(string text, U value) : base(text, value)
{
Foreground.Padding = new MarginPadding(2);
Masking = true;
CornerRadius = 6;
Children = new[]
{
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
chevron = new TextAwesome
{
AlwaysPresent = true,
Icon = FontAwesome.fa_chevron_right,
UseFullGlyphHeight = false,
Colour = Color4.Black,
Alpha = 0.5f,
TextSize = 8,
Margin = new MarginPadding { Left = 3, Right = 3 },
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
},
new OsuSpriteText {
Text = text,
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
}
}
}
};
}
private Color4? accentColour;
private TextAwesome chevron;
protected override void FormatForeground(bool hover = false)
{
base.FormatForeground(hover);
chevron.Alpha = hover ? 1 : 0;
}
public Color4 AccentColour
{
get { return accentColour.GetValueOrDefault(); }
set
{
accentColour = value;
BackgroundColourHover = BackgroundColourSelected = value;
FormatBackground();
FormatForeground();
}
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = Color4.Transparent;
BackgroundColourHover = accentColour ?? colours.PinkDarker;
BackgroundColourSelected = Color4.Black.Opacity(0.5f);
}
}
}

View File

@ -0,0 +1,172 @@
// 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.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface
{
public class OsuDropdown<T> : Dropdown<T>
{
protected override DropdownHeader CreateHeader() => new OsuDropdownHeader { AccentColour = AccentColour };
protected override Menu CreateMenu() => new OsuMenu();
private Color4? accentColour;
public virtual Color4 AccentColour
{
get { return accentColour.GetValueOrDefault(); }
set
{
accentColour = value;
if (Header != null)
((OsuDropdownHeader)Header).AccentColour = value;
foreach (var item in MenuItems.OfType<OsuDropdownMenuItem>())
item.AccentColour = value;
}
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == null)
AccentColour = colours.PinkDarker;
}
protected override DropdownMenuItem<T> CreateMenuItem(string text, T value) => new OsuDropdownMenuItem(text, value) { AccentColour = AccentColour };
private class OsuDropdownMenuItem : DropdownMenuItem<T>
{
public OsuDropdownMenuItem(string text, T value) : base(text, value)
{
Foreground.Padding = new MarginPadding(2);
Masking = true;
CornerRadius = 6;
Children = new[]
{
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
chevron = new TextAwesome
{
AlwaysPresent = true,
Icon = FontAwesome.fa_chevron_right,
UseFullGlyphHeight = false,
Colour = Color4.Black,
Alpha = 0.5f,
TextSize = 8,
Margin = new MarginPadding { Left = 3, Right = 3 },
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
},
new OsuSpriteText {
Text = text,
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
}
}
}
};
}
private Color4? accentColour;
private TextAwesome chevron;
protected override void FormatForeground(bool hover = false)
{
base.FormatForeground(hover);
chevron.Alpha = hover ? 1 : 0;
}
public Color4 AccentColour
{
get { return accentColour.GetValueOrDefault(); }
set
{
accentColour = value;
BackgroundColourHover = BackgroundColourSelected = value;
FormatBackground();
FormatForeground();
}
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = Color4.Transparent;
BackgroundColourHover = accentColour ?? colours.PinkDarker;
BackgroundColourSelected = Color4.Black.Opacity(0.5f);
}
}
protected class OsuDropdownHeader : DropdownHeader
{
private SpriteText label;
protected override string Label
{
get { return label.Text; }
set { label.Text = value; }
}
private Color4? accentColour;
public virtual Color4 AccentColour
{
get { return accentColour.GetValueOrDefault(); }
set
{
accentColour = value;
BackgroundColourHover = value;
}
}
public OsuDropdownHeader()
{
Foreground.Padding = new MarginPadding(4);
AutoSizeAxes = Axes.None;
Margin = new MarginPadding { Bottom = 4 };
CornerRadius = 4;
Height = 40;
Foreground.Children = new Drawable[]
{
label = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
},
new TextAwesome
{
Icon = FontAwesome.fa_chevron_down,
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Margin = new MarginPadding { Right = 4 },
TextSize = 20
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = Color4.Black.Opacity(0.5f);
BackgroundColourHover = accentColour ?? colours.PinkDarker;
}
}
}
}

View File

@ -0,0 +1,34 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface
{
public class OsuMenu : Menu
{
public OsuMenu()
{
CornerRadius = 4;
Background.Colour = Color4.Black.Opacity(0.5f);
ItemsContainer.Padding = new MarginPadding(5);
}
protected override void AnimateOpen() => FadeIn(300, EasingTypes.OutQuint);
protected override void AnimateClose() => FadeOut(300, EasingTypes.OutQuint);
protected override void UpdateContentHeight()
{
var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight;
ResizeTo(new Vector2(1, State == MenuState.Opened ? actualHeight : 0), 300, EasingTypes.OutQuint);
}
}
}

View File

@ -28,6 +28,8 @@ namespace osu.Game.Graphics.UserInterface
circle = new CircularContainer circle = new CircularContainer
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Masking = true,
Alpha = 0, Alpha = 0,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.8f, 0), Size = new Vector2(0.8f, 0),

View File

@ -6,21 +6,25 @@ using System.Linq;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface namespace osu.Game.Graphics.UserInterface
{ {
public class OsuTabControl<T> : TabControl<T> public class OsuTabControl<T> : TabControl<T>
{ {
protected override DropDownMenu<T> CreateDropDownMenu() => new OsuTabDropDownMenu<T>(); protected override Dropdown<T> CreateDropdown() => new OsuTabDropdown();
protected override TabItem<T> CreateTabItem(T value) => new OsuTabItem<T> { Value = value }; protected override TabItem<T> CreateTabItem(T value) => new OsuTabItem { Value = value };
protected override bool InternalContains(Vector2 screenSpacePos) => base.InternalContains(screenSpacePos) || DropDown.Contains(screenSpacePos); protected override bool InternalContains(Vector2 screenSpacePos) => base.InternalContains(screenSpacePos) || Dropdown.Contains(screenSpacePos);
public OsuTabControl() public OsuTabControl()
{ {
@ -45,42 +49,146 @@ namespace osu.Game.Graphics.UserInterface
set set
{ {
accentColour = value; accentColour = value;
var dropDown = DropDown as OsuTabDropDownMenu<T>; var dropDown = Dropdown as OsuTabDropdown;
if (dropDown != null) if (dropDown != null)
dropDown.AccentColour = value; dropDown.AccentColour = value;
foreach (var item in TabContainer.Children.OfType<OsuTabItem<T>>()) foreach (var item in TabContainer.Children.OfType<OsuTabItem>())
item.AccentColour = value; item.AccentColour = value;
} }
} }
public class OsuTabDropDownMenu<T1> : OsuDropDownMenu<T1> private class OsuTabItem : TabItem<T>
{ {
protected override DropDownHeader CreateHeader() => new OsuTabDropDownHeader private SpriteText text;
private Box box;
private Color4? accentColour;
public Color4 AccentColour
{
get { return accentColour.GetValueOrDefault(); }
set
{
accentColour = value;
if (!Active)
text.Colour = value;
}
}
public new T Value
{
get { return base.Value; }
set
{
base.Value = value;
text.Text = (value as Enum)?.GetDescription();
}
}
public override bool Active
{
get { return base.Active; }
set
{
if (Active == value) return;
if (value)
fadeActive();
else
fadeInactive();
base.Active = value;
}
}
private const float transition_length = 500;
private void fadeActive()
{
box.FadeIn(transition_length, EasingTypes.OutQuint);
text.FadeColour(Color4.White, transition_length, EasingTypes.OutQuint);
}
private void fadeInactive()
{
box.FadeOut(transition_length, EasingTypes.OutQuint);
text.FadeColour(AccentColour, transition_length, EasingTypes.OutQuint);
}
protected override bool OnHover(InputState state)
{
if (!Active)
fadeActive();
return true;
}
protected override void OnHoverLost(InputState state)
{
if (!Active)
fadeInactive();
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == null)
AccentColour = colours.Blue;
}
public OsuTabItem()
{
AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y;
Children = new Drawable[]
{
text = new OsuSpriteText
{
Margin = new MarginPadding(5),
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
TextSize = 14,
Font = @"Exo2.0-Bold", // Font should only turn bold when active?
},
box = new Box
{
RelativeSizeAxes = Axes.X,
Height = 1,
Alpha = 0,
Colour = Color4.White,
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
}
};
}
}
private class OsuTabDropdown : OsuDropdown<T>
{
protected override DropdownHeader CreateHeader() => new OsuTabDropdownHeader
{ {
AccentColour = AccentColour, AccentColour = AccentColour,
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
}; };
protected override DropDownMenuItem<T1> CreateDropDownItem(string key, T1 value) protected override DropdownMenuItem<T> CreateMenuItem(string text, T value)
{ {
var item = base.CreateDropDownItem(key, value); var item = base.CreateMenuItem(text, value);
item.ForegroundColourHover = Color4.Black; item.ForegroundColourHover = Color4.Black;
return item; return item;
} }
public OsuTabDropDownMenu() public OsuTabDropdown()
{ {
ContentContainer.Anchor = Anchor.TopRight; DropdownMenu.Anchor = Anchor.TopRight;
ContentContainer.Origin = Anchor.TopRight; DropdownMenu.Origin = Anchor.TopRight;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
ContentBackground.Colour = Color4.Black.Opacity(0.7f); DropdownMenu.Background.Colour = Color4.Black.Opacity(0.7f);
MaxDropDownHeight = 400; DropdownMenu.MaxHeight = 400;
} }
public class OsuTabDropDownHeader : OsuDropDownHeader protected class OsuTabDropdownHeader : OsuDropdownHeader
{ {
public override Color4 AccentColour public override Color4 AccentColour
{ {
@ -104,7 +212,7 @@ namespace osu.Game.Graphics.UserInterface
base.OnHoverLost(state); base.OnHoverLost(state);
} }
public OsuTabDropDownHeader() public OsuTabDropdownHeader()
{ {
RelativeSizeAxes = Axes.None; RelativeSizeAxes = Axes.None;
AutoSizeAxes = Axes.X; AutoSizeAxes = Axes.X;

View File

@ -1,121 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface
{
public class OsuTabItem<T> : TabItem<T>
{
private SpriteText text;
private Box box;
private Color4? accentColour;
public Color4 AccentColour
{
get { return accentColour.GetValueOrDefault(); }
set
{
accentColour = value;
if (!Active)
text.Colour = value;
}
}
public new T Value
{
get { return base.Value; }
set
{
base.Value = value;
text.Text = (value as Enum)?.GetDescription();
}
}
public override bool Active
{
get { return base.Active; }
set
{
if (Active == value) return;
if (value)
fadeActive();
else
fadeInactive();
base.Active = value;
}
}
private const float transition_length = 500;
private void fadeActive()
{
box.FadeIn(transition_length, EasingTypes.OutQuint);
text.FadeColour(Color4.White, transition_length, EasingTypes.OutQuint);
}
private void fadeInactive()
{
box.FadeOut(transition_length, EasingTypes.OutQuint);
text.FadeColour(AccentColour, transition_length, EasingTypes.OutQuint);
}
protected override bool OnHover(InputState state)
{
if (!Active)
fadeActive();
return true;
}
protected override void OnHoverLost(InputState state)
{
if (!Active)
fadeInactive();
}
public OsuTabItem()
{
AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y;
Children = new Drawable[]
{
text = new OsuSpriteText
{
Margin = new MarginPadding(5),
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
TextSize = 14,
Font = @"Exo2.0-Bold", // Font should only turn bold when active?
},
box = new Box
{
RelativeSizeAxes = Axes.X,
Height = 1,
Alpha = 0,
Colour = Color4.White,
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == null)
AccentColour = colours.Blue;
}
}
}

View File

@ -38,6 +38,9 @@ namespace osu.Game.Modes.Objects.Drawables
return; return;
state = value; state = value;
if (!IsLoaded)
return;
UpdateState(state); UpdateState(state);
if (State == ArmedState.Hit) if (State == ArmedState.Hit)

View File

@ -1,19 +1,63 @@
// 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 Newtonsoft.Json;
using osu.Game.Users;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Modes.Mods;
namespace osu.Game.Modes namespace osu.Game.Modes
{ {
public class Score public class Score
{ {
[JsonProperty(@"rank")]
public ScoreRank Rank { get; set; }
[JsonProperty(@"score")]
public double TotalScore { get; set; } public double TotalScore { get; set; }
public double Accuracy { get; set; } public double Accuracy { get; set; }
public double Health { get; set; } public double Health { get; set; }
[JsonProperty(@"maxcombo")]
public int MaxCombo { get; set; } public int MaxCombo { get; set; }
public int Combo { get; set; } public int Combo { get; set; }
public Mod[] Mods { get; set; }
public User User { get; set; }
[JsonProperty(@"replay_data")]
public Replay Replay; public Replay Replay;
public BeatmapInfo Beatmap; public BeatmapInfo Beatmap;
[JsonProperty(@"score_id")]
public long OnlineScoreID;
[JsonProperty(@"username")]
public string Username;
[JsonProperty(@"user_id")]
public long UserID;
[JsonProperty(@"date")]
public DateTime Date;
// [JsonProperty(@"count50")] 0,
//[JsonProperty(@"count100")] 0,
//[JsonProperty(@"count300")] 100,
//[JsonProperty(@"countmiss")] 0,
//[JsonProperty(@"countkatu")] 0,
//[JsonProperty(@"countgeki")] 31,
//[JsonProperty(@"perfect")] true,
//[JsonProperty(@"enabled_mods")] [
// "DT",
// "FL",
// "HD",
// "HR"
//],
//[JsonProperty(@"rank")] "XH",
//[JsonProperty(@"pp")] 26.1816,
//[JsonProperty(@"replay")] true
} }
} }

View File

@ -0,0 +1,29 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
namespace osu.Game.Modes
{
public enum ScoreRank
{
[Description(@"F")]
F,
[Description(@"F")]
D,
[Description(@"C")]
C,
[Description(@"B")]
B,
[Description(@"A")]
A,
[Description(@"S")]
S,
[Description(@"SPlus")]
SH,
[Description(@"SS")]
X,
[Description(@"SSPlus")]
XH,
}
}

View File

@ -58,13 +58,20 @@ namespace osu.Game.Online.API
public event APISuccessHandler Success; public event APISuccessHandler Success;
public event APIFailureHandler Failure; public event APIFailureHandler Failure;
private bool cancelled;
private Action pendingFailure;
public void Perform(APIAccess api) public void Perform(APIAccess api)
{ {
this.api = api;
if (checkAndProcessFailure())
return;
if (startTime == null) if (startTime == null)
startTime = DateTime.Now.TotalMilliseconds(); startTime = DateTime.Now.TotalMilliseconds();
this.api = api;
if (remainingTime <= 0) if (remainingTime <= 0)
throw new TimeoutException(@"API request timeout hit"); throw new TimeoutException(@"API request timeout hit");
@ -72,18 +79,41 @@ namespace osu.Game.Online.API
WebRequest.RetryCount = 0; WebRequest.RetryCount = 0;
WebRequest.Headers[@"Authorization"] = $@"Bearer {api.AccessToken}"; WebRequest.Headers[@"Authorization"] = $@"Bearer {api.AccessToken}";
WebRequest.BlockingPerform(); if (checkAndProcessFailure())
return;
if (!WebRequest.Aborted) //could have been aborted by a Cancel() call
WebRequest.BlockingPerform();
if (checkAndProcessFailure())
return;
api.Scheduler.Add(delegate { Success?.Invoke(); }); api.Scheduler.Add(delegate { Success?.Invoke(); });
} }
public void Cancel() => Fail(new OperationCanceledException(@"Request cancelled"));
public void Fail(Exception e) public void Fail(Exception e)
{ {
cancelled = true;
WebRequest?.Abort(); WebRequest?.Abort();
api.Scheduler.Add(delegate
{ pendingFailure = () => Failure?.Invoke(e);
Failure?.Invoke(e); checkAndProcessFailure();
}); }
/// <summary>
/// Checked for cancellation or error. Also queues up the Failed event if we can.
/// </summary>
/// <returns>Whether we are in a failed or cancelled state.</returns>
private bool checkAndProcessFailure()
{
if (api == null || pendingFailure == null) return cancelled;
api.Scheduler.Add(pendingFailure);
pendingFailure = null;
return true;
} }
} }

View File

@ -0,0 +1,40 @@
// 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 Newtonsoft.Json;
using osu.Framework.IO.Network;
using osu.Game.Database;
using osu.Game.Modes;
namespace osu.Game.Online.API.Requests
{
public class GetScoresRequest : APIRequest<GetScoresResponse>
{
private readonly BeatmapInfo beatmap;
public GetScoresRequest(BeatmapInfo beatmap)
{
this.beatmap = beatmap;
}
protected override WebRequest CreateWebRequest()
{
var req = base.CreateWebRequest();
req.AddParameter(@"c", beatmap.Hash);
req.AddParameter(@"f", beatmap.Path);
return req;
}
protected override string Target => @"beatmaps/scores";
}
public class GetScoresResponse
{
[JsonProperty(@"beatmap")]
public BeatmapInfo Beatmap;
[JsonProperty(@"scores")]
public IEnumerable<Score> Scores;
}
}

View File

@ -193,6 +193,7 @@ namespace osu.Game.Overlays.Dialog
{ {
Origin = Anchor.Centre, Origin = Anchor.Centre,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Masking = true,
BorderColour = Color4.White, BorderColour = Color4.White,
BorderThickness = 5f, BorderThickness = 5f,
Children = new Drawable[] Children = new Drawable[]

View File

@ -1,7 +1,7 @@
// 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 System.Collections.Generic;
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;
@ -10,13 +10,12 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using System.Collections.Generic;
namespace osu.Game.Overlays.Options namespace osu.Game.Overlays.Options
{ {
public class OptionDropDown<T> : FillFlowContainer public class OptionDropdown<T> : FillFlowContainer
{ {
private DropDownMenu<T> dropdown; private Dropdown<T> dropdown;
private SpriteText text; private SpriteText text;
public string LabelText public string LabelText
@ -33,12 +32,8 @@ namespace osu.Game.Overlays.Options
get { return bindable; } get { return bindable; }
set set
{ {
if (bindable != null)
bindable.ValueChanged -= bindable_ValueChanged;
bindable = value; bindable = value;
bindable.ValueChanged += bindable_ValueChanged; dropdown.SelectedValue.BindTo(bindable);
bindable_ValueChanged(null, null);
if (bindable.Disabled) if (bindable.Disabled)
Alpha = 0.3f; Alpha = 0.3f;
} }
@ -46,23 +41,6 @@ namespace osu.Game.Overlays.Options
private Bindable<T> bindable; private Bindable<T> bindable;
private void bindable_ValueChanged(object sender, EventArgs e)
{
dropdown.SelectedValue = bindable.Value;
}
private void dropdown_ValueChanged(object sender, EventArgs e)
{
bindable.Value = dropdown.SelectedValue;
}
protected override void Dispose(bool isDisposing)
{
bindable.ValueChanged -= bindable_ValueChanged;
dropdown.ValueChanged -= dropdown_ValueChanged;
base.Dispose(isDisposing);
}
private IEnumerable<KeyValuePair<string, T>> items; private IEnumerable<KeyValuePair<string, T>> items;
public IEnumerable<KeyValuePair<string, T>> Items public IEnumerable<KeyValuePair<string, T>> Items
{ {
@ -73,19 +51,12 @@ namespace osu.Game.Overlays.Options
set set
{ {
items = value; items = value;
if(dropdown != null) if (dropdown != null)
{
dropdown.Items = value; dropdown.Items = value;
// We need to refresh the dropdown because our items changed,
// thus its selected value may be outdated.
if (bindable != null)
dropdown.SelectedValue = bindable.Value;
}
} }
} }
public OptionDropDown() public OptionDropdown()
{ {
Items = new KeyValuePair<string, T>[0]; Items = new KeyValuePair<string, T>[0];
@ -97,14 +68,13 @@ namespace osu.Game.Overlays.Options
text = new OsuSpriteText { text = new OsuSpriteText {
Alpha = 0, Alpha = 0,
}, },
dropdown = new OsuDropDownMenu<T> dropdown = new OsuDropdown<T>
{ {
Margin = new MarginPadding { Top = 5 }, Margin = new MarginPadding { Top = 5 },
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Items = Items, Items = Items,
} }
}; };
dropdown.ValueChanged += dropdown_ValueChanged;
} }
} }
} }

View File

@ -8,9 +8,9 @@ using System.Collections.Generic;
namespace osu.Game.Overlays.Options namespace osu.Game.Overlays.Options
{ {
public class OptionEnumDropDown<T> : OptionDropDown<T> public class OptionEnumDropdown<T> : OptionDropdown<T>
{ {
public OptionEnumDropDown() public OptionEnumDropdown()
{ {
if (!typeof(T).IsEnum) if (!typeof(T).IsEnum)
throw new InvalidOperationException("OptionsDropdown only supports enums as the generic type argument"); throw new InvalidOperationException("OptionsDropdown only supports enums as the generic type argument");

View File

@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Options.Sections.Audio
protected override string Header => "Devices"; protected override string Header => "Devices";
private AudioManager audio; private AudioManager audio;
private OptionDropDown<string> dropdown; private OptionDropdown<string> dropdown;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(AudioManager audio) private void load(AudioManager audio)
@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Options.Sections.Audio
Children = new Drawable[] Children = new Drawable[]
{ {
dropdown = new OptionDropDown<string> dropdown = new OptionDropdown<string>
{ {
Bindable = audio.AudioDevice Bindable = audio.AudioDevice
}, },

View File

@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Options.Sections.Debug
{ {
Children = new Drawable[] Children = new Drawable[]
{ {
new OptionEnumDropDown<GCLatencyMode> new OptionEnumDropdown<GCLatencyMode>
{ {
LabelText = "Active mode", LabelText = "Active mode",
Bindable = config.GetBindable<GCLatencyMode>(FrameworkDebugConfig.ActiveGCMode) Bindable = config.GetBindable<GCLatencyMode>(FrameworkDebugConfig.ActiveGCMode)

View File

@ -23,12 +23,12 @@ namespace osu.Game.Overlays.Options.Sections.Gameplay
LabelText = "Background dim", LabelText = "Background dim",
Bindable = (BindableInt)config.GetBindable<int>(OsuConfig.DimLevel) Bindable = (BindableInt)config.GetBindable<int>(OsuConfig.DimLevel)
}, },
new OptionEnumDropDown<ProgressBarType> new OptionEnumDropdown<ProgressBarType>
{ {
LabelText = "Progress display", LabelText = "Progress display",
Bindable = config.GetBindable<ProgressBarType>(OsuConfig.ProgressBarType) Bindable = config.GetBindable<ProgressBarType>(OsuConfig.ProgressBarType)
}, },
new OptionEnumDropDown<ScoreMeterType> new OptionEnumDropdown<ScoreMeterType>
{ {
LabelText = "Score meter type", LabelText = "Score meter type",
Bindable = config.GetBindable<ScoreMeterType>(OsuConfig.ScoreMeter) Bindable = config.GetBindable<ScoreMeterType>(OsuConfig.ScoreMeter)

View File

@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Options.Sections.General
{ {
Children = new Drawable[] Children = new Drawable[]
{ {
new OptionEnumDropDown<ReleaseStream> new OptionEnumDropdown<ReleaseStream>
{ {
LabelText = "Release stream", LabelText = "Release stream",
Bindable = config.GetBindable<ReleaseStream>(OsuConfig.ReleaseStream), Bindable = config.GetBindable<ReleaseStream>(OsuConfig.ReleaseStream),

View File

@ -57,7 +57,7 @@ namespace osu.Game.Overlays.Options.Sections.Graphics
LabelText = "Softening filter", LabelText = "Softening filter",
Bindable = config.GetBindable<bool>(OsuConfig.BloomSoftening) Bindable = config.GetBindable<bool>(OsuConfig.BloomSoftening)
}, },
new OptionEnumDropDown<ScreenshotFormat> new OptionEnumDropdown<ScreenshotFormat>
{ {
LabelText = "Screenshot", LabelText = "Screenshot",
Bindable = config.GetBindable<ScreenshotFormat>(OsuConfig.ScreenshotFormat) Bindable = config.GetBindable<ScreenshotFormat>(OsuConfig.ScreenshotFormat)

View File

@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Options.Sections.Graphics
Children = new Drawable[] Children = new Drawable[]
{ {
new OptionLabel { Text = "Resolution: TODO dropdown" }, new OptionLabel { Text = "Resolution: TODO dropdown" },
new OptionEnumDropDown<WindowMode> new OptionEnumDropdown<WindowMode>
{ {
LabelText = "Screen mode", LabelText = "Screen mode",
Bindable = config.GetBindable<WindowMode>(FrameworkConfig.WindowMode), Bindable = config.GetBindable<WindowMode>(FrameworkConfig.WindowMode),

View File

@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Options.Sections.Graphics
Children = new Drawable[] Children = new Drawable[]
{ {
// TODO: this needs to be a custom dropdown at some point // TODO: this needs to be a custom dropdown at some point
new OptionEnumDropDown<FrameSync> new OptionEnumDropdown<FrameSync>
{ {
LabelText = "Frame limiter", LabelText = "Frame limiter",
Bindable = config.GetBindable<FrameSync>(FrameworkConfig.FrameSync) Bindable = config.GetBindable<FrameSync>(FrameworkConfig.FrameSync)

View File

@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Options.Sections.Input
LabelText = "Map absolute raw input to the osu! window", LabelText = "Map absolute raw input to the osu! window",
Bindable = config.GetBindable<bool>(OsuConfig.AbsoluteToOsuWindow) Bindable = config.GetBindable<bool>(OsuConfig.AbsoluteToOsuWindow)
}, },
new OptionEnumDropDown<ConfineMouseMode> new OptionEnumDropdown<ConfineMouseMode>
{ {
LabelText = "Confine mouse cursor", LabelText = "Confine mouse cursor",
Bindable = config.GetBindable<ConfineMouseMode>(OsuConfig.ConfineMouse), Bindable = config.GetBindable<ConfineMouseMode>(OsuConfig.ConfineMouse),

View File

@ -61,8 +61,13 @@ namespace osu.Game.Overlays.Options.Sections
}, },
new OptionSlider<double> new OptionSlider<double>
{ {
LabelText = "Cursor size", LabelText = "Menu cursor size",
Bindable = (BindableDouble)config.GetBindable<double>(OsuConfig.CursorSize) Bindable = (BindableDouble)config.GetBindable<double>(OsuConfig.MenuCursorSize)
},
new OptionSlider<double>
{
LabelText = "Gameplay cursor size",
Bindable = (BindableDouble)config.GetBindable<double>(OsuConfig.GameplayCursorSize)
}, },
new OsuCheckbox new OsuCheckbox
{ {
@ -72,4 +77,4 @@ namespace osu.Game.Overlays.Options.Sections
}; };
} }
} }
} }

View File

@ -1,14 +1,12 @@
// 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.Diagnostics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
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;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Users;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
@ -26,7 +24,20 @@ namespace osu.Game.Overlays.Toolbar
Add(new OpaqueBackground { Depth = 1 }); Add(new OpaqueBackground { Depth = 1 });
Flow.Add(avatar = new Avatar()); Flow.Add(avatar = new Avatar
{
Masking = true,
Size = new Vector2(32),
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
CornerRadius = 4,
EdgeEffect = new EdgeEffect
{
Type = EdgeEffectType.Shadow,
Radius = 4,
Colour = Color4.Black.Opacity(0.1f),
}
});
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -49,86 +60,5 @@ namespace osu.Game.Overlays.Toolbar
break; break;
} }
} }
public class Avatar : Container
{
public Drawable Sprite;
private int userId;
private OsuGame game;
private Texture guestTexture;
public Avatar()
{
Size = new Vector2(32);
Anchor = Anchor.CentreLeft;
Origin = Anchor.CentreLeft;
CornerRadius = Size.X / 8;
EdgeEffect = new EdgeEffect
{
Type = EdgeEffectType.Shadow,
Radius = 4,
Colour = Color4.Black.Opacity(0.1f),
};
Masking = true;
}
[BackgroundDependencyLoader]
private void load(OsuGame game, TextureStore textures)
{
this.game = game;
guestTexture = textures.Get(@"Online/avatar-guest");
}
public int UserId
{
get { return userId; }
set
{
if (userId == value)
return;
userId = value;
var newSprite = userId > 1 ? new OnlineSprite($@"https://a.ppy.sh/{userId}") : new Sprite { Texture = guestTexture };
newSprite.FillMode = FillMode.Fit;
newSprite.LoadAsync(game, s =>
{
Sprite?.FadeOut();
Sprite?.Expire();
Sprite = s;
Add(s);
//todo: fix this... clock dependencies are a pain
if (s.Clock != null)
s.FadeInFromZero(200);
});
}
}
public class OnlineSprite : Sprite
{
private readonly string url;
public OnlineSprite(string url)
{
Debug.Assert(url != null);
this.url = url;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Texture = textures.Get(url);
}
}
}
} }
} }

View File

@ -91,8 +91,10 @@ namespace osu.Game.Screens.Menu
logoContainer = new CircularContainer logoContainer = new CircularContainer
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Scale = new Vector2(0.8f), Scale = new Vector2(0.8f),
Masking = true,
Children = new Drawable[] Children = new Drawable[]
{ {
colourAndTriangles = new Container colourAndTriangles = new Container

View File

@ -71,6 +71,8 @@ namespace osu.Game.Screens
BackgroundScreen bg = CreateBackground(); BackgroundScreen bg = CreateBackground();
OnBeatmapChanged(Beatmap);
if (lastOsu?.Background != null) if (lastOsu?.Background != null)
{ {
if (bg == null || lastOsu.Background.Equals(bg)) if (bg == null || lastOsu.Background.Equals(bg))

View File

@ -0,0 +1,39 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Modes;
using osu.Framework.Extensions;
namespace osu.Game.Screens.Select.Leaderboards
{
public class DrawableRank : Container
{
private Sprite sprite;
public ScoreRank Rank { get; private set; }
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
sprite.Texture = textures.Get($@"Badges/ScoreRanks/{Rank.GetDescription()}");
}
public DrawableRank(ScoreRank rank)
{
Rank = rank;
Children = new Drawable[]
{
sprite = new Sprite
{
RelativeSizeAxes = Axes.Both,
},
};
}
}
}

View File

@ -0,0 +1,111 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Game.Modes;
using System;
namespace osu.Game.Screens.Select.Leaderboards
{
public class Leaderboard : Container
{
private ScrollContainer scrollContainer;
private FillFlowContainer<LeaderboardScore> scrollFlow;
private IEnumerable<Score> scores;
public IEnumerable<Score> Scores
{
get { return scores; }
set
{
scores = value;
int i = 150;
if (scores == null)
{
foreach (var c in scrollFlow.Children)
c.FadeOut(i += 10);
foreach (var c in scrollFlow.Children)
c.LifetimeEnd = Time.Current + i;
return;
}
scrollFlow.Clear();
i = 0;
foreach (var s in scores)
{
var ls = new LeaderboardScore(s, 1 + i)
{
AlwaysPresent = true,
State = Visibility.Hidden,
};
scrollFlow.Add(ls);
ls.Delay(i++ * 50, true);
ls.Show();
}
scrollContainer.ScrollTo(0f, false);
}
}
public Leaderboard()
{
Children = new Drawable[]
{
scrollContainer = new ScrollContainer
{
RelativeSizeAxes = Axes.Both,
ScrollDraggerVisible = false,
Children = new Drawable[]
{
scrollFlow = new FillFlowContainer<LeaderboardScore>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0f, 5f),
Padding = new MarginPadding(5),
},
},
},
};
}
protected override void Update()
{
base.Update();
var fadeStart = scrollContainer.Current + scrollContainer.DrawHeight;
if (!scrollContainer.IsScrolledToEnd())
fadeStart -= LeaderboardScore.HEIGHT;
foreach (var c in scrollFlow.Children)
{
var topY = c.ToSpaceOfOtherDrawable(Vector2.Zero, scrollFlow).Y;
var bottomY = topY + LeaderboardScore.HEIGHT;
if (bottomY < fadeStart)
c.Colour = Color4.White;
else if (topY > fadeStart + LeaderboardScore.HEIGHT)
c.Colour = Color4.Transparent;
else
{
c.ColourInfo = ColourInfo.GradientVertical(
Color4.White.Opacity(Math.Min(1 - (topY - fadeStart) / LeaderboardScore.HEIGHT, 1)),
Color4.White.Opacity(Math.Min(1 - (bottomY - fadeStart) / LeaderboardScore.HEIGHT, 1)));
}
}
}
}
}

View File

@ -0,0 +1,386 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes;
using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Modes.Mods;
using osu.Game.Users;
using osu.Framework;
namespace osu.Game.Screens.Select.Leaderboards
{
public class LeaderboardScore : Container, IStateful<Visibility>
{
public static readonly float HEIGHT = 60;
public readonly int RankPosition;
public readonly Score Score;
private const float corner_radius = 5;
private const float edge_margin = 5;
private const float background_alpha = 0.25f;
private const float rank_width = 30;
private Box background;
private Container content, avatar;
private DrawableRank scoreRank;
private OsuSpriteText nameLabel;
private GlowingSpriteText scoreLabel;
private ScoreComponentLabel maxCombo, accuracy;
private Container flagBadgeContainer;
private FillFlowContainer<ScoreModIcon> modsContainer;
private Visibility state;
public Visibility State
{
get { return state; }
set
{
state = value;
switch (state)
{
case Visibility.Hidden:
foreach (var d in new Drawable[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, maxCombo, accuracy, modsContainer })
d.FadeOut();
Alpha = 0;
content.MoveToY(75);
avatar.MoveToX(75);
nameLabel.MoveToX(150);
break;
case Visibility.Visible:
FadeIn(200);
content.MoveToY(0, 800, EasingTypes.OutQuint);
Delay(100, true);
avatar.FadeIn(300, EasingTypes.OutQuint);
nameLabel.FadeIn(350, EasingTypes.OutQuint);
avatar.MoveToX(0, 300, EasingTypes.OutQuint);
nameLabel.MoveToX(0, 350, EasingTypes.OutQuint);
Delay(250, true);
scoreLabel.FadeIn(200);
scoreRank.FadeIn(200);
Delay(50, true);
var drawables = new Drawable[] { flagBadgeContainer, maxCombo, accuracy, modsContainer, };
for (int i = 0; i < drawables.Length; i++)
{
drawables[i].FadeIn(100 + i * 50);
}
break;
}
}
}
public LeaderboardScore(Score score, int rank)
{
Score = score;
RankPosition = rank;
RelativeSizeAxes = Axes.X;
Height = HEIGHT;
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Y,
Width = rank_width,
Children = new[]
{
new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = @"Exo2.0-MediumItalic",
TextSize = 22,
Text = RankPosition.ToString(),
},
},
},
content = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = rank_width, },
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
CornerRadius = corner_radius,
Masking = true,
Children = new[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Alpha = background_alpha,
},
},
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(edge_margin),
Children = new Drawable[]
{
avatar = new Avatar
{
Size = new Vector2(HEIGHT - edge_margin * 2, HEIGHT - edge_margin * 2),
CornerRadius = corner_radius,
Masking = true,
EdgeEffect = new EdgeEffect
{
Type = EdgeEffectType.Shadow,
Radius = 1,
Colour = Color4.Black.Opacity(0.2f),
},
UserId = Score.User?.Id ?? Score.UserID,
},
new Container
{
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
Position = new Vector2(HEIGHT - edge_margin, 0f),
Children = new Drawable[]
{
nameLabel = new OsuSpriteText
{
Text = Score.User?.Username ?? Score.Username,
Font = @"Exo2.0-BoldItalic",
TextSize = 23,
},
new FillFlowContainer
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(10f, 0f),
Children = new Drawable[]
{
flagBadgeContainer = new Container
{
Size = new Vector2(87f, 20f),
Masking = true,
Children = new Drawable[]
{
new DrawableFlag(Score.User?.Country?.FlagName ?? "__")
{
Width = 30,
RelativeSizeAxes = Axes.Y,
},
},
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(10f, 0f),
Margin = new MarginPadding { Left = edge_margin, },
Children = new Drawable[]
{
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString()),
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:0}" : @"{0:0.00}", Score.Accuracy)),
},
},
},
},
},
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5f, 0f),
Children = new Drawable[]
{
scoreLabel = new GlowingSpriteText(Score.TotalScore.ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")),
new Container
{
Size = new Vector2(40f, 20f),
Children = new[]
{
scoreRank = new DrawableRank(Score.Rank)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(40f),
},
},
},
},
},
modsContainer = new FillFlowContainer<ScoreModIcon>
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
},
},
},
},
},
};
if (Score.Mods != null)
{
foreach (Mod mod in Score.Mods)
{
// TODO: Get actual mod colours
modsContainer.Add(new ScoreModIcon(mod.Icon, OsuColour.FromHex(@"ffcc22")));
}
}
}
public void ToggleVisibility() => State = State == Visibility.Visible ? Visibility.Hidden : Visibility.Visible;
public override void Hide() => State = Visibility.Hidden;
public override void Show() => State = Visibility.Visible;
protected override bool OnHover(Framework.Input.InputState state)
{
background.FadeTo(0.5f, 300, EasingTypes.OutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(Framework.Input.InputState state)
{
background.FadeTo(background_alpha, 200, EasingTypes.OutQuint);
base.OnHoverLost(state);
}
private class GlowingSpriteText : Container
{
public GlowingSpriteText(string text, string font, int textSize, Color4 textColour, Color4 glowColour)
{
AutoSizeAxes = Axes.Both;
Children = new Drawable[]
{
new BufferedContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
BlurSigma = new Vector2(4),
CacheDrawnFrameBuffer = true,
RelativeSizeAxes = Axes.Both,
BlendingMode = BlendingMode.Additive,
Size = new Vector2(3f),
Children = new[]
{
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = font,
TextSize = textSize,
FixedWidth = true,
Text = text,
Colour = glowColour,
Shadow = false,
},
},
},
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = font,
FixedWidth = true,
TextSize = textSize,
Text = text,
Colour = textColour,
Shadow = false,
},
};
}
}
private class ScoreModIcon : Container
{
public ScoreModIcon(FontAwesome icon, Color4 colour)
{
AutoSizeAxes = Axes.Both;
Children = new[]
{
new TextAwesome
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Icon = FontAwesome.fa_osu_mod_bg,
Colour = colour,
Shadow = true,
TextSize = 30,
UseFullGlyphHeight = false,
},
new TextAwesome
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Icon = icon,
Colour = OsuColour.Gray(84),
TextSize = 18,
Position = new Vector2(0f, 2f),
UseFullGlyphHeight = false,
},
};
}
}
private class ScoreComponentLabel : Container
{
public ScoreComponentLabel(FontAwesome icon, string value)
{
Anchor = Anchor.CentreLeft;
Origin = Anchor.CentreLeft;
Size = new Vector2(60f, 20f);
Padding = new MarginPadding { Top = 10f, };
Children = new Drawable[]
{
new TextAwesome
{
Origin = Anchor.Centre,
Icon = FontAwesome.fa_square,
Colour = OsuColour.FromHex(@"3087ac"),
Rotation = 45,
Shadow = true,
},
new TextAwesome
{
Origin = Anchor.Centre,
Icon = icon,
Colour = OsuColour.FromHex(@"a4edff"),
Scale = new Vector2(0.8f),
},
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
{
Origin = Anchor.CentreLeft,
Margin = new MarginPadding { Left = 15, },
},
};
}
}
}
}

View File

@ -8,9 +8,11 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Screens.Edit; using osu.Game.Screens.Edit;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Screens.Select.Leaderboards;
namespace osu.Game.Screens.Select namespace osu.Game.Screens.Select
{ {
@ -18,6 +20,7 @@ namespace osu.Game.Screens.Select
{ {
private OsuScreen player; private OsuScreen player;
private ModSelectOverlay modSelect; private ModSelectOverlay modSelect;
private Leaderboard leaderboard;
public PlaySongSelect() public PlaySongSelect()
{ {
@ -28,6 +31,11 @@ namespace osu.Game.Screens.Select
Anchor = Anchor.BottomCentre, Anchor = Anchor.BottomCentre,
Margin = new MarginPadding { Bottom = 50 } Margin = new MarginPadding { Bottom = 50 }
}); });
LeftContent.Add(leaderboard = new Leaderboard
{
RelativeSizeAxes = Axes.Both,
});
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -44,12 +52,29 @@ namespace osu.Game.Screens.Select
}, Key.Number3); }, Key.Number3);
} }
private GetScoresRequest getScoresRequest;
protected override void OnBeatmapChanged(WorkingBeatmap beatmap) protected override void OnBeatmapChanged(WorkingBeatmap beatmap)
{ {
beatmap?.Mods.BindTo(modSelect.SelectedMods); beatmap?.Mods.BindTo(modSelect.SelectedMods);
updateLeaderboard(beatmap);
base.OnBeatmapChanged(beatmap); base.OnBeatmapChanged(beatmap);
} }
private void updateLeaderboard(WorkingBeatmap beatmap)
{
leaderboard.Scores = null;
getScoresRequest?.Cancel();
if (beatmap?.BeatmapInfo == null) return;
getScoresRequest = new GetScoresRequest(beatmap.BeatmapInfo);
getScoresRequest.Success += r => leaderboard.Scores = r.Scores;
Game.API.Queue(getScoresRequest);
}
protected override void OnResuming(Screen last) protected override void OnResuming(Screen last)
{ {
player = null; player = null;

View File

@ -39,9 +39,15 @@ namespace osu.Game.Screens.Select
private TrackManager trackManager; private TrackManager trackManager;
private DialogOverlay dialogOverlay; private DialogOverlay dialogOverlay;
private static readonly Vector2 wedged_container_size = new Vector2(0.5f, 225);
private static readonly Vector2 wedged_container_size = new Vector2(0.5f, 245);
private const float left_area_padding = 20;
private BeatmapInfoWedge beatmapInfoWedge; private BeatmapInfoWedge beatmapInfoWedge;
protected Container LeftContent;
private static readonly Vector2 background_blur = new Vector2(20); private static readonly Vector2 background_blur = new Vector2(20);
private CancellationTokenSource initialAddSetsTask; private CancellationTokenSource initialAddSetsTask;
@ -81,6 +87,20 @@ namespace osu.Game.Screens.Select
} }
} }
}); });
Add(LeftContent = new Container
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(wedged_container_size.X, 1),
Padding = new MarginPadding
{
Bottom = 50,
Top = wedged_container_size.Y + left_area_padding,
Left = left_area_padding,
Right = left_area_padding * 2,
}
});
Add(carousel = new BeatmapCarousel Add(carousel = new BeatmapCarousel
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
@ -104,8 +124,8 @@ namespace osu.Game.Screens.Select
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Margin = new MarginPadding Margin = new MarginPadding
{ {
Top = 20, Top = left_area_padding,
Right = 20, Right = left_area_padding,
}, },
X = -50, X = -50,
}); });

View File

@ -21,6 +21,7 @@ using osu.Game.Screens.Tournament.Components;
using osu.Game.Screens.Tournament.Teams; using osu.Game.Screens.Tournament.Teams;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament namespace osu.Game.Screens.Tournament
{ {
@ -36,7 +37,7 @@ namespace osu.Game.Screens.Tournament
private GroupContainer groupsContainer; private GroupContainer groupsContainer;
private OsuSpriteText fullTeamNameText; private OsuSpriteText fullTeamNameText;
private List<Team> allTeams = new List<Team>(); private List<Country> allTeams = new List<Country>();
private DrawingsConfigManager drawingsConfig; private DrawingsConfigManager drawingsConfig;
@ -238,7 +239,7 @@ namespace osu.Game.Screens.Tournament
reset(true); reset(true);
} }
private void onTeamSelected(Team team) private void onTeamSelected(Country team)
{ {
groupsContainer.AddTeam(team); groupsContainer.AddTeam(team);
@ -275,7 +276,7 @@ namespace osu.Game.Screens.Tournament
teamsContainer.ClearTeams(); teamsContainer.ClearTeams();
allTeams.Clear(); allTeams.Clear();
foreach (Team t in TeamList.Teams) foreach (Country t in TeamList.Teams)
{ {
if (groupsContainer.ContainsTeam(t.FullName)) if (groupsContainer.ContainsTeam(t.FullName))
continue; continue;
@ -311,7 +312,7 @@ namespace osu.Game.Screens.Tournament
if (line.ToUpper().StartsWith("GROUP")) if (line.ToUpper().StartsWith("GROUP"))
continue; continue;
Team teamToAdd = allTeams.FirstOrDefault(t => t.FullName == line); Country teamToAdd = allTeams.FirstOrDefault(t => t.FullName == line);
if (teamToAdd == null) if (teamToAdd == null)
continue; continue;

View File

@ -11,9 +11,9 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Screens.Tournament.Teams;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament namespace osu.Game.Screens.Tournament
{ {
@ -73,7 +73,7 @@ namespace osu.Game.Screens.Tournament
}; };
} }
public void AddTeam(Team team) public void AddTeam(Country team)
{ {
GroupTeam gt = new GroupTeam(team); GroupTeam gt = new GroupTeam(team);
@ -91,7 +91,7 @@ namespace osu.Game.Screens.Tournament
return allTeams.Any(t => t.Team.FullName == fullName); return allTeams.Any(t => t.Team.FullName == fullName);
} }
public bool RemoveTeam(Team team) public bool RemoveTeam(Country team)
{ {
allTeams.RemoveAll(gt => gt.Team == team); allTeams.RemoveAll(gt => gt.Team == team);
@ -122,12 +122,12 @@ namespace osu.Game.Screens.Tournament
private class GroupTeam : Container private class GroupTeam : Container
{ {
public Team Team; public Country Team;
private FillFlowContainer innerContainer; private FillFlowContainer innerContainer;
private Sprite flagSprite; private Sprite flagSprite;
public GroupTeam(Team team) public GroupTeam(Country team)
{ {
Team = team; Team = team;

View File

@ -7,8 +7,8 @@ using System.Linq;
using System.Text; using System.Text;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Screens.Tournament.Teams;
using OpenTK; using OpenTK;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament namespace osu.Game.Screens.Tournament
{ {
@ -64,7 +64,7 @@ namespace osu.Game.Screens.Tournament
} }
} }
public void AddTeam(Team team) public void AddTeam(Country team)
{ {
if (groups[currentGroup].TeamsCount == maxTeams) if (groups[currentGroup].TeamsCount == maxTeams)
return; return;

View File

@ -13,18 +13,18 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms; using osu.Framework.Graphics.Transforms;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Screens.Tournament.Teams;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament namespace osu.Game.Screens.Tournament
{ {
public class ScrollingTeamContainer : Container public class ScrollingTeamContainer : Container
{ {
public event Action OnScrollStarted; public event Action OnScrollStarted;
public event Action<Team> OnSelected; public event Action<Country> OnSelected;
private readonly List<Team> availableTeams = new List<Team>(); private readonly List<Country> availableTeams = new List<Country>();
private Container tracker; private Container tracker;
@ -158,7 +158,7 @@ namespace osu.Game.Screens.Tournament
} }
} }
public void AddTeam(Team team) public void AddTeam(Country team)
{ {
if (availableTeams.Contains(team)) if (availableTeams.Contains(team))
return; return;
@ -169,12 +169,12 @@ namespace osu.Game.Screens.Tournament
scrollState = ScrollState.Idle; scrollState = ScrollState.Idle;
} }
public void AddTeams(IEnumerable<Team> teams) public void AddTeams(IEnumerable<Country> teams)
{ {
if (teams == null) if (teams == null)
return; return;
foreach (Team t in teams) foreach (Country t in teams)
AddTeam(t); AddTeam(t);
} }
@ -185,7 +185,7 @@ namespace osu.Game.Screens.Tournament
scrollState = ScrollState.Idle; scrollState = ScrollState.Idle;
} }
public void RemoveTeam(Team team) public void RemoveTeam(Country team)
{ {
availableTeams.Remove(team); availableTeams.Remove(team);
@ -270,7 +270,7 @@ namespace osu.Game.Screens.Tournament
private void addFlags() private void addFlags()
{ {
foreach (Team t in availableTeams) foreach (Country t in availableTeams)
{ {
Add(new ScrollingTeam(t) Add(new ScrollingTeam(t)
{ {
@ -326,7 +326,7 @@ namespace osu.Game.Screens.Tournament
public const float WIDTH = 58; public const float WIDTH = 58;
public const float HEIGHT = 41; public const float HEIGHT = 41;
public Team Team; public Country Team;
private Sprite flagSprite; private Sprite flagSprite;
private Box outline; private Box outline;
@ -346,7 +346,7 @@ namespace osu.Game.Screens.Tournament
} }
} }
public ScrollingTeam(Team team) public ScrollingTeam(Country team)
{ {
Team = team; Team = team;

View File

@ -2,11 +2,12 @@
// 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 osu.Game.Users;
namespace osu.Game.Screens.Tournament.Teams namespace osu.Game.Screens.Tournament.Teams
{ {
public interface ITeamList public interface ITeamList
{ {
IEnumerable<Team> Teams { get; } IEnumerable<Country> Teams { get; }
} }
} }

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament.Teams namespace osu.Game.Screens.Tournament.Teams
{ {
@ -20,11 +21,11 @@ namespace osu.Game.Screens.Tournament.Teams
this.storage = storage; this.storage = storage;
} }
public IEnumerable<Team> Teams public IEnumerable<Country> Teams
{ {
get get
{ {
var teams = new List<Team>(); var teams = new List<Country>();
try try
{ {
@ -52,7 +53,7 @@ namespace osu.Game.Screens.Tournament.Teams
string acronym = split.Length >= 3 ? split[2].Trim() : teamName; string acronym = split.Length >= 3 ? split[2].Trim() : teamName;
acronym = acronym.Substring(0, Math.Min(3, acronym.Length)); acronym = acronym.Substring(0, Math.Min(3, acronym.Length));
teams.Add(new Team teams.Add(new Country
{ {
FlagName = flagName, FlagName = flagName,
FullName = teamName, FullName = teamName,

View File

@ -1,23 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Screens.Tournament.Teams
{
public class Team
{
/// <summary>
/// The name of this team.
/// </summary>
public string FullName;
/// <summary>
/// Short acronym which appears in the group boxes post-selection.
/// </summary>
public string Acronym;
/// <summary>
/// Two-letter flag acronym (ISO 3166 standard)
/// </summary>
public string FlagName;
}
}

114
osu.Game/Users/Avatar.cs Normal file
View File

@ -0,0 +1,114 @@
// 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.Diagnostics;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Users
{
public class Avatar : Container
{
public Drawable Sprite;
private long userId;
private OsuGameBase game;
private Texture guestTexture;
[BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuGameBase game, TextureStore textures)
{
this.game = game;
guestTexture = textures.Get(@"Online/avatar-guest");
}
public long UserId
{
get { return userId; }
set
{
if (userId == value)
return;
userId = value;
invalidateSprite();
}
}
private Task loadTask;
private void invalidateSprite()
{
Sprite?.FadeOut(100);
Sprite?.Expire();
Sprite = null;
}
private void updateSprite()
{
if (loadTask != null || Sprite != null) return;
var newSprite = userId > 1 ? new OnlineSprite($@"https://a.ppy.sh/{userId}", guestTexture) : new Sprite { Texture = guestTexture };
newSprite.FillMode = FillMode.Fill;
loadTask = newSprite.LoadAsync(game, s =>
{
Sprite = s;
Add(Sprite);
Sprite.FadeInFromZero(200);
loadTask = null;
});
}
private double timeVisible;
private bool shouldUpdate => Sprite != null || timeVisible > 500;
protected override void Update()
{
base.Update();
if (!shouldUpdate)
{
//Special optimisation to not start loading until we are within bounds of our closest ScrollContainer parent.
ScrollContainer scroll = null;
IContainer cursor = this;
while (scroll == null && (cursor = cursor.Parent) != null)
scroll = cursor as ScrollContainer;
if (scroll?.ScreenSpaceDrawQuad.Intersects(ScreenSpaceDrawQuad) ?? true)
timeVisible += Time.Elapsed;
else
timeVisible = 0;
}
if (shouldUpdate)
updateSprite();
}
public class OnlineSprite : Sprite
{
private readonly string url;
private readonly Texture fallbackTexture;
public OnlineSprite(string url, Texture fallbackTexture = null)
{
Debug.Assert(url != null);
this.url = url;
this.fallbackTexture = fallbackTexture;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Texture = textures.Get(url) ?? fallbackTexture;
}
}
}
}

67
osu.Game/Users/Country.cs Normal file
View 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 osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Users
{
public class Country
{
/// <summary>
/// The name of this country.
/// </summary>
public string FullName;
/// <summary>
/// Short acronym which appears in the group boxes post-selection.
/// </summary>
public string Acronym;
/// <summary>
/// Two-letter flag acronym (ISO 3166 standard)
/// </summary>
public string FlagName;
}
public class DrawableFlag : Container
{
private Sprite sprite;
private TextureStore textures;
private string flagName;
public string FlagName
{
get { return flagName; }
set
{
if (value == flagName) return;
flagName = value;
sprite.Texture = textures.Get($@"Flags/{flagName}");
}
}
[BackgroundDependencyLoader]
private void load(TextureStore ts)
{
textures = ts;
sprite.Texture = textures.Get($@"Flags/{flagName}");
}
public DrawableFlag(string name = @"__")
{
flagName = name;
Children = new Drawable[]
{
sprite = new Sprite
{
RelativeSizeAxes = Axes.Both,
},
};
}
}
}

10
osu.Game/Users/Team.cs Normal file
View File

@ -0,0 +1,10 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Users
{
public class Team
{
public string Name;
}
}

View File

@ -7,5 +7,7 @@ namespace osu.Game.Users
{ {
public int Id; public int Id;
public string Username; public string Username;
public Country Country;
public Team Team;
} }
} }

View File

@ -86,6 +86,7 @@
<Compile Include="Graphics\UserInterface\BackButton.cs" /> <Compile Include="Graphics\UserInterface\BackButton.cs" />
<Compile Include="Graphics\UserInterface\FocusedTextBox.cs" /> <Compile Include="Graphics\UserInterface\FocusedTextBox.cs" />
<Compile Include="Graphics\UserInterface\Nub.cs" /> <Compile Include="Graphics\UserInterface\Nub.cs" />
<Compile Include="Graphics\UserInterface\OsuMenu.cs" />
<Compile Include="Graphics\UserInterface\OsuPasswordTextBox.cs" /> <Compile Include="Graphics\UserInterface\OsuPasswordTextBox.cs" />
<Compile Include="Graphics\UserInterface\OsuSliderBar.cs" /> <Compile Include="Graphics\UserInterface\OsuSliderBar.cs" />
<Compile Include="Graphics\UserInterface\OsuTextBox.cs" /> <Compile Include="Graphics\UserInterface\OsuTextBox.cs" />
@ -129,6 +130,7 @@
<Compile Include="Modes\UI\StandardHealthDisplay.cs" /> <Compile Include="Modes\UI\StandardHealthDisplay.cs" />
<Compile Include="Modes\UI\StandardHudOverlay.cs" /> <Compile Include="Modes\UI\StandardHudOverlay.cs" />
<Compile Include="Online\API\IOnlineComponent.cs" /> <Compile Include="Online\API\IOnlineComponent.cs" />
<Compile Include="Online\API\Requests\GetScoresRequest.cs" />
<Compile Include="Online\API\Requests\GetUserRequest.cs" /> <Compile Include="Online\API\Requests\GetUserRequest.cs" />
<Compile Include="Overlays\DragBar.cs" /> <Compile Include="Overlays\DragBar.cs" />
<Compile Include="Overlays\LoginOverlay.cs" /> <Compile Include="Overlays\LoginOverlay.cs" />
@ -159,9 +161,7 @@
<Compile Include="Overlays\Notifications\SimpleNotification.cs" /> <Compile Include="Overlays\Notifications\SimpleNotification.cs" />
<Compile Include="Overlays\Options\OptionDropDown.cs" /> <Compile Include="Overlays\Options\OptionDropDown.cs" />
<Compile Include="Overlays\Options\OptionLabel.cs" /> <Compile Include="Overlays\Options\OptionLabel.cs" />
<Compile Include="Graphics\UserInterface\OsuDropDownHeader.cs" /> <Compile Include="Graphics\UserInterface\OsuDropdown.cs" />
<Compile Include="Graphics\UserInterface\OsuDropDownMenu.cs" />
<Compile Include="Graphics\UserInterface\OsuDropDownMenuItem.cs" />
<Compile Include="Overlays\Options\OptionsFooter.cs" /> <Compile Include="Overlays\Options\OptionsFooter.cs" />
<Compile Include="Overlays\Options\Sections\DebugSection.cs" /> <Compile Include="Overlays\Options\Sections\DebugSection.cs" />
<Compile Include="Overlays\Options\Sections\Debug\GeneralOptions.cs" /> <Compile Include="Overlays\Options\Sections\Debug\GeneralOptions.cs" />
@ -241,7 +241,7 @@
<Compile Include="Online\API\OAuth.cs" /> <Compile Include="Online\API\OAuth.cs" />
<Compile Include="Online\API\OAuthToken.cs" /> <Compile Include="Online\API\OAuthToken.cs" />
<Compile Include="Online\API\Requests\GetMessagesRequest.cs" /> <Compile Include="Online\API\Requests\GetMessagesRequest.cs" />
<Compile Include="Online\API\Requests\ListChannels.cs" /> <Compile Include="Online\API\Requests\ListChannelsRequest.cs" />
<Compile Include="Online\Chat\Channel.cs" /> <Compile Include="Online\Chat\Channel.cs" />
<Compile Include="Online\Chat\Drawables\DrawableChannel.cs" /> <Compile Include="Online\Chat\Drawables\DrawableChannel.cs" />
<Compile Include="Online\Chat\Drawables\ChatLine.cs" /> <Compile Include="Online\Chat\Drawables\ChatLine.cs" />
@ -265,7 +265,6 @@
<Compile Include="Screens\Tournament\GroupContainer.cs" /> <Compile Include="Screens\Tournament\GroupContainer.cs" />
<Compile Include="Screens\Tournament\Teams\ITeamList.cs" /> <Compile Include="Screens\Tournament\Teams\ITeamList.cs" />
<Compile Include="Screens\Tournament\ScrollingTeamContainer.cs" /> <Compile Include="Screens\Tournament\ScrollingTeamContainer.cs" />
<Compile Include="Screens\Tournament\Teams\Team.cs" />
<Compile Include="Screens\Tournament\Teams\StorageBackedTeamList.cs" /> <Compile Include="Screens\Tournament\Teams\StorageBackedTeamList.cs" />
<Compile Include="Users\User.cs" /> <Compile Include="Users\User.cs" />
<Compile Include="Graphics\UserInterface\Volume\VolumeControl.cs" /> <Compile Include="Graphics\UserInterface\Volume\VolumeControl.cs" />
@ -280,6 +279,7 @@
<Compile Include="Database\BeatmapMetadata.cs" /> <Compile Include="Database\BeatmapMetadata.cs" />
<Compile Include="Database\BeatmapInfo.cs" /> <Compile Include="Database\BeatmapInfo.cs" />
<Compile Include="Database\BaseDifficulty.cs" /> <Compile Include="Database\BaseDifficulty.cs" />
<Compile Include="Database\DatabaseWorkingBeatmap.cs" />
<Compile Include="Graphics\UserInterface\OsuButton.cs" /> <Compile Include="Graphics\UserInterface\OsuButton.cs" />
<Compile Include="Overlays\Options\Sections\MaintenanceSection.cs" /> <Compile Include="Overlays\Options\Sections\MaintenanceSection.cs" />
<Compile Include="Overlays\Options\OptionsSection.cs" /> <Compile Include="Overlays\Options\OptionsSection.cs" />
@ -354,8 +354,14 @@
<Compile Include="Overlays\WaveOverlayContainer.cs" /> <Compile Include="Overlays\WaveOverlayContainer.cs" />
<Compile Include="Screens\Select\Options\BeatmapOptionsButton.cs" /> <Compile Include="Screens\Select\Options\BeatmapOptionsButton.cs" />
<Compile Include="Screens\Select\Options\BeatmapOptionsOverlay.cs" /> <Compile Include="Screens\Select\Options\BeatmapOptionsOverlay.cs" />
<Compile Include="Screens\Select\Leaderboards\Leaderboard.cs" />
<Compile Include="Screens\Select\Leaderboards\LeaderboardScore.cs" />
<Compile Include="Users\Country.cs" />
<Compile Include="Users\Team.cs" />
<Compile Include="Modes\ScoreRank.cs" />
<Compile Include="Users\Avatar.cs" />
<Compile Include="Screens\Select\Leaderboards\DrawableRank.cs" />
<Compile Include="Graphics\UserInterface\OsuTabControl.cs" /> <Compile Include="Graphics\UserInterface\OsuTabControl.cs" />
<Compile Include="Graphics\UserInterface\OsuTabItem.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="$(SolutionDir)\osu-framework\osu.Framework\osu.Framework.csproj"> <ProjectReference Include="$(SolutionDir)\osu-framework\osu.Framework\osu.Framework.csproj">
@ -377,6 +383,7 @@
<ItemGroup /> <ItemGroup />
<ItemGroup /> <ItemGroup />
<ItemGroup /> <ItemGroup />
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.