1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 21:02:55 +08:00

Merge branch 'master' into right-mouse-scrollbar

This commit is contained in:
Dan Balasescu 2017-07-14 19:15:00 +10:00 committed by GitHub
commit 3914b3ba13
16 changed files with 1039 additions and 317 deletions

View File

@ -8,6 +8,7 @@ using osu.Game.Screens.Multiplayer;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Users; using osu.Game.Users;
using osu.Game.Database; using osu.Game.Database;
using osu.Framework.Allocation;
namespace osu.Desktop.VisualTests.Tests namespace osu.Desktop.VisualTests.Tests
{ {
@ -15,74 +16,117 @@ namespace osu.Desktop.VisualTests.Tests
{ {
public override string Description => @"Select your favourite room"; public override string Description => @"Select your favourite room";
private RulesetDatabase rulesets;
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();
DrawableRoom first; DrawableRoom first;
DrawableRoom second;
Add(new FillFlowContainer Add(new FillFlowContainer
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Width = 500f, Width = 580f,
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Children = new Drawable[] Children = new Drawable[]
{ {
first = new DrawableRoom(new Room()), first = new DrawableRoom(new Room
second = new DrawableRoom(new Room()),
}
});
first.Room.Name.Value = @"Great Room Right Here";
first.Room.Host.Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" } };
first.Room.Status.Value = new RoomStatusOpen();
first.Room.Beatmap.Value = new BeatmapInfo
{ {
Name = { Value = @"Great Room Right Here" },
Host = { Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" } } },
Status = { Value = new RoomStatusOpen() },
Type = { Value = new GameTypeTeamVersus() },
Beatmap =
{
Value = new BeatmapInfo
{
StarDifficulty = 4.65,
Ruleset = rulesets.GetRuleset(3),
Metadata = new BeatmapMetadata Metadata = new BeatmapMetadata
{ {
Title = @"Seiryu", Title = @"Critical Crystal",
Artist = @"Critical Crystal", Artist = @"Seiryu",
}, },
}; BeatmapSet = new BeatmapSetInfo
second.Room.Name.Value = @"Relax It's The Weekend";
second.Room.Host.Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" } };
second.Room.Status.Value = new RoomStatusPlaying();
second.Room.Beatmap.Value = new BeatmapInfo
{ {
OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Cover = @"https://assets.ppy.sh//beatmaps/376340/covers/cover.jpg?1456478455",
},
},
},
},
},
Participants =
{
Value = new[]
{
new User { GlobalRank = 1355 },
new User { GlobalRank = 8756 },
},
},
}),
new DrawableRoom(new Room
{
Name = { Value = @"Relax It's The Weekend" },
Host = { Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" } } },
Status = { Value = new RoomStatusPlaying() },
Type = { Value = new GameTypeTagTeam() },
Beatmap =
{
Value = new BeatmapInfo
{
StarDifficulty = 1.96,
Ruleset = rulesets.GetRuleset(0),
Metadata = new BeatmapMetadata Metadata = new BeatmapMetadata
{ {
Title = @"Serendipity", Title = @"Serendipity",
Artist = @"ZAQ", Artist = @"ZAQ",
}, },
}; BeatmapSet = new BeatmapSetInfo
AddStep(@"change state", () =>
{ {
first.Room.Status.Value = new RoomStatusPlaying(); OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Cover = @"https://assets.ppy.sh//beatmaps/526839/covers/cover.jpg?1493815706",
},
},
},
},
},
Participants =
{
Value = new[]
{
new User { GlobalRank = 578975 },
new User { GlobalRank = 24554 },
},
},
}),
}
}); });
AddStep(@"change name", () => AddStep(@"change title", () => first.Room.Name.Value = @"I Changed Name");
AddStep(@"change host", () => first.Room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } });
AddStep(@"change status", () => first.Room.Status.Value = new RoomStatusPlaying());
AddStep(@"change type", () => first.Room.Type.Value = new GameTypeVersus());
AddStep(@"change beatmap", () => first.Room.Beatmap.Value = null);
AddStep(@"change participants", () => first.Room.Participants.Value = new[]
{ {
first.Room.Name.Value = @"I Changed Name"; new User { GlobalRank = 1254 },
new User { GlobalRank = 123189 },
}); });
}
AddStep(@"change host", () => [BackgroundDependencyLoader]
private void load(RulesetDatabase rulesets)
{ {
first.Room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } }; this.rulesets = rulesets;
});
AddStep(@"change beatmap", () =>
{
first.Room.Beatmap.Value = null;
});
AddStep(@"change state", () =>
{
first.Room.Status.Value = new RoomStatusOpen();
});
} }
} }
} }

View File

@ -0,0 +1,27 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Game.Overlays;
using osu.Game.Users;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseMedalOverlay : TestCase
{
public override string Description => @"medal get!";
public TestCaseMedalOverlay()
{
AddStep(@"display", () =>
{
LoadComponentAsync(new MedalOverlay(new Medal
{
Name = @"Animations",
InternalName = @"all-intro-doubletime",
Description = @"More complex than you think.",
}), Add);
});
}
}
}

View File

@ -231,6 +231,7 @@
<Compile Include="Tests\TestCaseDirect.cs" /> <Compile Include="Tests\TestCaseDirect.cs" />
<Compile Include="Tests\TestCaseSocial.cs" /> <Compile Include="Tests\TestCaseSocial.cs" />
<Compile Include="Tests\TestCaseBreadcrumbs.cs" /> <Compile Include="Tests\TestCaseBreadcrumbs.cs" />
<Compile Include="Tests\TestCaseMedalOverlay.cs" />
<Compile Include="Tests\TestCaseRoomInspector.cs" /> <Compile Include="Tests\TestCaseRoomInspector.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />

View File

@ -0,0 +1,28 @@
// 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.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Database;
namespace osu.Game.Beatmaps.Drawables
{
public class BeatmapSetCover : Sprite
{
private readonly BeatmapSetInfo set;
public BeatmapSetCover(BeatmapSetInfo set)
{
this.set = set;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
string resource = set.OnlineInfo.Covers.Cover;
if (resource != null)
Texture = textures.Get(resource);
}
}
}

View File

@ -52,10 +52,32 @@ namespace osu.Game.Online.Multiplayer
public override string Name => "Tag Team"; public override string Name => "Tag Team";
public override Drawable GetIcon(OsuColour colours, float size) public override Drawable GetIcon(OsuColour colours, float size)
{ {
return new VersusRow(colours.Blue, colours.Blue, size * 0.6f) return new FillFlowContainer
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(2f),
Children = new[]
{
new TextAwesome
{
Icon = FontAwesome.fa_refresh,
TextSize = size * 0.75f,
Colour = colours.Blue,
Shadow = false,
UseFullGlyphHeight = false,
},
new TextAwesome
{
Icon = FontAwesome.fa_refresh,
TextSize = size * 0.75f,
Colour = colours.Pink,
Shadow = false,
UseFullGlyphHeight = false,
},
},
}; };
} }
} }

View File

@ -3,11 +3,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using OpenTK; using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps.Drawables; using osu.Game.Beatmaps.Drawables;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -34,7 +32,7 @@ namespace osu.Game.Overlays.Direct
return icons; return icons;
} }
protected Drawable CreateBackground() => new DelayedLoadWrapper(new BeatmapSetBackgroundSprite(SetInfo) protected Drawable CreateBackground() => new DelayedLoadWrapper(new BeatmapSetCover(SetInfo)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
@ -89,23 +87,5 @@ namespace osu.Game.Overlays.Direct
Value = value; Value = value;
} }
} }
private class BeatmapSetBackgroundSprite : Sprite
{
private readonly BeatmapSetInfo set;
public BeatmapSetBackgroundSprite(BeatmapSetInfo set)
{
this.set = set;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
string resource = set.OnlineInfo.Covers.Card;
if (resource != null)
Texture = textures.Get(resource);
}
}
} }
} }

View File

@ -0,0 +1,304 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Sprites;
using osu.Game.Users;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Overlays.MedalSplash;
using osu.Framework.Allocation;
using osu.Framework.Audio.Sample;
using osu.Framework.Audio;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input;
using OpenTK.Input;
using System.Linq;
using osu.Framework.Graphics.Shapes;
using System;
using osu.Framework.MathUtils;
namespace osu.Game.Overlays
{
public class MedalOverlay : FocusedOverlayContainer
{
public const float DISC_SIZE = 400;
private const float border_width = 5;
private readonly Medal medal;
private readonly Box background;
private readonly Container backgroundStrip, particleContainer;
private readonly BackgroundStrip leftStrip, rightStrip;
private readonly CircularContainer disc;
private readonly Sprite innerSpin, outerSpin;
private DrawableMedal drawableMedal;
private SampleChannel getSample;
public MedalOverlay(Medal medal)
{
this.medal = medal;
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(60),
},
outerSpin = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(DISC_SIZE + 500),
Alpha = 0f,
},
backgroundStrip = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
Height = border_width,
Alpha = 0f,
Children = new[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.CentreRight,
Width = 0.5f,
Padding = new MarginPadding { Right = DISC_SIZE / 2 },
Children = new[]
{
leftStrip = new BackgroundStrip(0f, 1f)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
},
},
},
new Container
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.CentreLeft,
Width = 0.5f,
Padding = new MarginPadding { Left = DISC_SIZE / 2 },
Children = new[]
{
rightStrip = new BackgroundStrip(1f, 0f),
},
},
},
},
particleContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Alpha = 0f,
},
disc = new CircularContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0f,
Masking = true,
AlwaysPresent = true,
BorderColour = Color4.White,
BorderThickness = border_width,
Size = new Vector2(DISC_SIZE),
Scale = new Vector2(0.8f),
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"05262f"),
},
new Triangles
{
RelativeSizeAxes = Axes.Both,
TriangleScale = 2,
ColourDark = OsuColour.FromHex(@"04222b"),
ColourLight = OsuColour.FromHex(@"052933"),
},
innerSpin = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(1.05f),
Alpha = 0.25f,
},
},
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, TextureStore textures, AudioManager audio)
{
getSample = audio.Sample.Get(@"MedalSplash/medal-get");
innerSpin.Texture = outerSpin.Texture = textures.Get(@"MedalSplash/disc-spin");
disc.EdgeEffect = leftStrip.EdgeEffect = rightStrip.EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = colours.Blue.Opacity(0.5f),
Radius = 50,
};
disc.Add(drawableMedal = new DrawableMedal(medal)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
});
}
protected override void LoadComplete()
{
base.LoadComplete();
Show();
}
protected override void Update()
{
base.Update();
particleContainer.Add(new MedalParticle(RNG.Next(0, 359)));
}
protected override bool OnClick(InputState state)
{
dismiss();
return true;
}
protected override void OnFocusLost(InputState state)
{
if (state.Keyboard.Keys.Contains(Key.Escape)) dismiss();
}
private const double initial_duration = 400;
private const double step_duration = 900;
protected override void PopIn()
{
base.PopIn();
FadeIn(200);
background.FlashColour(Color4.White.Opacity(0.25f), 400);
getSample.Play();
using (innerSpin.BeginLoopedSequence())
innerSpin.RotateTo(360, 20000);
using (outerSpin.BeginLoopedSequence())
outerSpin.RotateTo(360, 40000);
using (BeginDelayedSequence(200, true))
{
disc.FadeIn(initial_duration);
particleContainer.FadeIn(initial_duration);
outerSpin.FadeTo(0.1f, initial_duration * 2);
disc.ScaleTo(1f, initial_duration * 2, EasingTypes.OutElastic);
using (BeginDelayedSequence(initial_duration + 200, true))
{
backgroundStrip.FadeIn(step_duration);
leftStrip.ResizeWidthTo(1f, step_duration, EasingTypes.OutQuint);
rightStrip.ResizeWidthTo(1f, step_duration, EasingTypes.OutQuint);
Schedule(() => { if (drawableMedal.State != DisplayState.Full) drawableMedal.State = DisplayState.Icon; });
using (BeginDelayedSequence(step_duration, true))
{
Schedule(() => { if (drawableMedal.State != DisplayState.Full) drawableMedal.State = DisplayState.MedalUnlocked; });
using (BeginDelayedSequence(step_duration, true))
Schedule(() => { if (drawableMedal.State != DisplayState.Full) drawableMedal.State = DisplayState.Full; });
}
}
}
}
protected override void PopOut()
{
base.PopOut();
FadeOut(200);
}
private void dismiss()
{
if (drawableMedal.State != DisplayState.Full)
{
// if we haven't yet, play out the animation fully
drawableMedal.State = DisplayState.Full;
Flush(true);
return;
}
Hide();
Expire();
}
private class BackgroundStrip : Container
{
public BackgroundStrip(float start, float end)
{
RelativeSizeAxes = Axes.Both;
Width = 0f;
ColourInfo = ColourInfo.GradientHorizontal(Color4.White.Opacity(start), Color4.White.Opacity(end));
Masking = true;
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.White,
}
};
}
}
private class MedalParticle : CircularContainer
{
private readonly float direction;
private Vector2 positionForOffset(float offset) => new Vector2((float)(offset * Math.Sin(direction)), (float)(offset * Math.Cos(direction)));
public MedalParticle(float direction)
{
this.direction = direction;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Position = positionForOffset(DISC_SIZE / 2);
Masking = true;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = colours.Blue.Opacity(0.5f),
Radius = 5,
};
MoveTo(positionForOffset(DISC_SIZE / 2 + 200), 500);
FadeOut(500);
Expire();
}
}
}
}

View File

@ -0,0 +1,183 @@
// 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;
using OpenTK;
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.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Users;
namespace osu.Game.Overlays.MedalSplash
{
public class DrawableMedal : Container, IStateful<DisplayState>
{
private const float scale_when_unlocked = 0.76f;
private const float scale_when_full = 0.6f;
private readonly Medal medal;
private readonly Container medalContainer;
private readonly Sprite medalSprite, medalGlow;
private readonly OsuSpriteText unlocked, name;
private readonly TextFlowContainer description;
private readonly FillFlowContainer infoFlow;
private DisplayState state;
public DrawableMedal(Medal medal)
{
this.medal = medal;
Position = new Vector2(0f, MedalOverlay.DISC_SIZE / 2);
Children = new Drawable[]
{
medalContainer = new Container
{
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Alpha = 0f,
Children = new Drawable[]
{
medalSprite = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(0.81f),
},
medalGlow = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
},
},
unlocked = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = "Medal Unlocked".ToUpper(),
TextSize = 24,
Font = @"Exo2.0-Light",
Alpha = 0f,
Scale = new Vector2(1f / scale_when_unlocked),
},
infoFlow = new FillFlowContainer
{
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Width = 0.6f,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0f, 5f),
Children = new Drawable[]
{
name = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = medal.Name,
TextSize = 20,
Font = @"Exo2.0-Bold",
Alpha = 0f,
Scale = new Vector2(1f / scale_when_full),
},
description = new TextFlowContainer
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Alpha = 0f,
Scale = new Vector2(1f / scale_when_full),
},
},
},
};
description.AddText(medal.Description, s =>
{
s.Anchor = Anchor.TopCentre;
s.Origin = Anchor.TopCentre;
s.TextSize = 16;
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, TextureStore textures)
{
medalSprite.Texture = textures.Get(medal.ImageUrl);
medalGlow.Texture = textures.Get(@"MedalSplash/medal-glow");
description.Colour = colours.BlueLight;
unlocked.Position = new Vector2(0f, medalContainer.Size.Y / 2 + 10);
infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90);
}
protected override void LoadComplete()
{
base.LoadComplete();
updateState();
}
public DisplayState State
{
get { return state; }
set
{
if (state == value) return;
state = value;
updateState();
}
}
private void updateState()
{
if (!IsLoaded) return;
const double duration = 900;
switch (state)
{
case DisplayState.None:
medalContainer.ScaleTo(0);
break;
case DisplayState.Icon:
medalContainer.ScaleTo(1, duration, EasingTypes.OutElastic);
medalContainer.FadeIn(duration);
break;
case DisplayState.MedalUnlocked:
medalContainer.ScaleTo(1);
medalContainer.Show();
ScaleTo(scale_when_unlocked, duration, EasingTypes.OutExpo);
MoveToY(MedalOverlay.DISC_SIZE / 2 - 30, duration, EasingTypes.OutExpo);
unlocked.FadeInFromZero(duration);
break;
case DisplayState.Full:
medalContainer.ScaleTo(1);
medalContainer.Show();
ScaleTo(scale_when_full, duration, EasingTypes.OutExpo);
MoveToY(MedalOverlay.DISC_SIZE / 2 - 60, duration, EasingTypes.OutExpo);
name.FadeInFromZero(duration + 100);
description.FadeInFromZero(duration * 2);
break;
}
}
}
public enum DisplayState
{
None,
Icon,
MedalUnlocked,
Full,
}
}

View File

@ -4,11 +4,13 @@
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration;
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.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
@ -20,20 +22,25 @@ namespace osu.Game.Screens.Multiplayer
{ {
public class DrawableRoom : OsuClickableContainer public class DrawableRoom : OsuClickableContainer
{ {
private const float content_padding = 5; private const float transition_duration = 100;
private const float height = 90; private const float content_padding = 10;
private const float height = 100;
private const float side_strip_width = 5;
private const float cover_width = 145;
private readonly Box sideStrip; private readonly Box sideStrip;
private readonly UpdateableAvatar avatar; private readonly Container coverContainer;
private readonly OsuSpriteText name; private readonly OsuSpriteText name, status, beatmapTitle, beatmapDash, beatmapArtist;
private readonly Container flagContainer;
private readonly OsuSpriteText host;
private readonly OsuSpriteText rankBounds;
private readonly OsuSpriteText status;
private readonly FillFlowContainer<OsuSpriteText> beatmapInfoFlow; private readonly FillFlowContainer<OsuSpriteText> beatmapInfoFlow;
private readonly OsuSpriteText beatmapTitle; private readonly ParticipantInfo participantInfo;
private readonly OsuSpriteText beatmapDash; private readonly ModeTypeInfo modeTypeInfo;
private readonly OsuSpriteText beatmapArtist;
private readonly Bindable<string> nameBind = new Bindable<string>();
private readonly Bindable<User> hostBind = new Bindable<User>();
private readonly Bindable<RoomStatus> statusBind = new Bindable<RoomStatus>();
private readonly Bindable<GameType> typeBind = new Bindable<GameType>();
private readonly Bindable<BeatmapInfo> beatmapBind = new Bindable<BeatmapInfo>();
private readonly Bindable<User[]> participantsBind = new Bindable<User[]>();
private OsuColour colours; private OsuColour colours;
private LocalisationEngine localisation; private LocalisationEngine localisation;
@ -60,24 +67,41 @@ namespace osu.Game.Screens.Multiplayer
new Box new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(34), Colour = OsuColour.FromHex(@"212121"),
}, },
sideStrip = new Box sideStrip = new Box
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
Width = content_padding, Width = side_strip_width,
}, },
avatar = new UpdateableAvatar new Container
{ {
Size = new Vector2(Height - content_padding * 2), Width = cover_width,
RelativeSizeAxes = Axes.Y,
Masking = true, Masking = true,
CornerRadius = 5f, Margin = new MarginPadding { Left = side_strip_width },
Margin = new MarginPadding { Left = content_padding * 2, Top = content_padding }, Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
coverContainer = new Container
{
RelativeSizeAxes = Axes.Both,
},
},
}, },
new Container new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = content_padding, Bottom = content_padding, Left = Height + content_padding * 2, Right = content_padding }, Padding = new MarginPadding
{
Vertical = content_padding,
Left = side_strip_width + cover_width + content_padding,
Right = content_padding,
},
Children = new Drawable[] Children = new Drawable[]
{ {
new FillFlowContainer new FillFlowContainer
@ -92,56 +116,7 @@ namespace osu.Game.Screens.Multiplayer
{ {
TextSize = 18, TextSize = 18,
}, },
new Container participantInfo = new ParticipantInfo(),
{
RelativeSizeAxes = Axes.X,
Height = 20f,
Children = new Drawable[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5f, 0f),
Children = new Drawable[]
{
flagContainer = new Container
{
Width = 30f,
RelativeSizeAxes = Axes.Y,
},
new Container
{
Width = 40f,
RelativeSizeAxes = Axes.Y,
},
new OsuSpriteText
{
Text = "hosted by",
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = 14,
},
host = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = 14,
Font = @"Exo2.0-BoldItalic",
},
},
},
rankBounds = new OsuSpriteText
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Text = "#0 - #0",
TextSize = 14,
Margin = new MarginPadding { Right = 10 },
},
},
},
}, },
}, },
new FillFlowContainer new FillFlowContainer
@ -151,7 +126,6 @@ namespace osu.Game.Screens.Multiplayer
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Margin = new MarginPadding { Bottom = content_padding },
Children = new Drawable[] Children = new Drawable[]
{ {
status = new OsuSpriteText status = new OsuSpriteText
@ -174,7 +148,7 @@ namespace osu.Game.Screens.Multiplayer
beatmapDash = new OsuSpriteText beatmapDash = new OsuSpriteText
{ {
TextSize = 14, TextSize = 14,
Font = @"Exo2.0-RegularItalic", Font = @"Exo2.0-BoldItalic",
}, },
beatmapArtist = new OsuSpriteText beatmapArtist = new OsuSpriteText
{ {
@ -185,14 +159,26 @@ namespace osu.Game.Screens.Multiplayer
}, },
}, },
}, },
modeTypeInfo = new ModeTypeInfo
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
},
}, },
}, },
}; };
Room.Name.ValueChanged += displayName; nameBind.ValueChanged += displayName;
Room.Host.ValueChanged += displayUser; hostBind.ValueChanged += displayUser;
Room.Status.ValueChanged += displayStatus; typeBind.ValueChanged += displayGameType;
Room.Beatmap.ValueChanged += displayBeatmap; participantsBind.ValueChanged += displayParticipants;
nameBind.BindTo(Room.Name);
hostBind.BindTo(Room.Host);
statusBind.BindTo(Room.Status);
typeBind.BindTo(Room.Type);
beatmapBind.BindTo(Room.Beatmap);
participantsBind.BindTo(Room.Participants);
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -201,10 +187,14 @@ namespace osu.Game.Screens.Multiplayer
this.localisation = localisation; this.localisation = localisation;
this.colours = colours; this.colours = colours;
beatmapInfoFlow.Colour = rankBounds.Colour = colours.Gray9; beatmapInfoFlow.Colour = colours.Gray9;
host.Colour = colours.Blue;
displayStatus(Room.Status.Value); //binded here instead of ctor because dependencies are needed
statusBind.ValueChanged += displayStatus;
beatmapBind.ValueChanged += displayBeatmap;
statusBind.TriggerChange();
beatmapBind.TriggerChange();
} }
private void displayName(string value) private void displayName(string value)
@ -214,9 +204,7 @@ namespace osu.Game.Screens.Multiplayer
private void displayUser(User value) private void displayUser(User value)
{ {
avatar.User = value; participantInfo.Host = value;
host.Text = value.Username;
flagContainer.Children = new[] { new DrawableFlag(value.Country?.FlagName ?? @"__") { RelativeSizeAxes = Axes.Both } };
} }
private void displayStatus(RoomStatus value) private void displayStatus(RoomStatus value)
@ -228,33 +216,48 @@ namespace osu.Game.Screens.Multiplayer
d.FadeColour(value.GetAppropriateColour(colours), 100); d.FadeColour(value.GetAppropriateColour(colours), 100);
} }
private void displayGameType(GameType value)
{
modeTypeInfo.Type = value;
}
private void displayBeatmap(BeatmapInfo value) private void displayBeatmap(BeatmapInfo value)
{ {
modeTypeInfo.Beatmap = value;
if (value != null) if (value != null)
{ {
coverContainer.FadeIn(transition_duration);
coverContainer.Children = new[]
{
new AsyncLoadWrapper(new BeatmapSetCover(value.BeatmapSet)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
FillMode = FillMode.Fill,
OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out),
}) { RelativeSizeAxes = Axes.Both },
};
beatmapTitle.Current = localisation.GetUnicodePreference(value.Metadata.TitleUnicode, value.Metadata.Title); beatmapTitle.Current = localisation.GetUnicodePreference(value.Metadata.TitleUnicode, value.Metadata.Title);
beatmapDash.Text = @" - "; beatmapDash.Text = @" - ";
beatmapArtist.Current = localisation.GetUnicodePreference(value.Metadata.ArtistUnicode, value.Metadata.Artist); beatmapArtist.Current = localisation.GetUnicodePreference(value.Metadata.ArtistUnicode, value.Metadata.Artist);
} }
else else
{ {
coverContainer.FadeOut(transition_duration);
beatmapTitle.Current = null; beatmapTitle.Current = null;
beatmapArtist.Current = null; beatmapArtist.Current = null;
beatmapTitle.Text = @"Changing map"; beatmapTitle.Text = "Changing map";
beatmapDash.Text = string.Empty; beatmapDash.Text = beatmapArtist.Text = string.Empty;
beatmapArtist.Text = string.Empty;
} }
} }
protected override void Dispose(bool isDisposing) private void displayParticipants(User[] value)
{ {
Room.Name.ValueChanged -= displayName; participantInfo.Participants = value;
Room.Host.ValueChanged -= displayUser;
Room.Status.ValueChanged -= displayStatus;
Room.Beatmap.ValueChanged -= displayBeatmap;
base.Dispose(isDisposing);
} }
} }
} }

View File

@ -0,0 +1,82 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Database;
using osu.Game.Online.Multiplayer;
namespace osu.Game.Screens.Multiplayer
{
public class ModeTypeInfo : Container
{
private const float height = 30;
private const float transition_duration = 100;
private readonly Container rulesetContainer, gameTypeContainer;
public BeatmapInfo Beatmap
{
set
{
if (value != null)
{
rulesetContainer.FadeIn(transition_duration);
rulesetContainer.Children = new[]
{
new DifficultyIcon(value)
{
Size = new Vector2(height),
},
};
}
else
{
rulesetContainer.FadeOut(transition_duration);
}
}
}
public GameType Type
{
set
{
gameTypeContainer.Children = new[]
{
new DrawableGameType(value)
{
Size = new Vector2(height),
},
};
}
}
public ModeTypeInfo()
{
AutoSizeAxes = Axes.Both;
Children = new[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5f, 0f),
Children = new[]
{
rulesetContainer = new Container
{
AutoSizeAxes = Axes.Both,
},
gameTypeContainer = new Container
{
AutoSizeAxes = Axes.Both,
},
},
},
};
}
}
}

View File

@ -0,0 +1,145 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Users;
namespace osu.Game.Screens.Multiplayer
{
public class ParticipantInfo : Container
{
private readonly Container flagContainer;
private readonly OsuSpriteText host;
private readonly FillFlowContainer levelRangeContainer;
private readonly OsuSpriteText levelRangeLower;
private readonly OsuSpriteText levelRangeHigher;
public User Host
{
set
{
host.Text = value.Username;
flagContainer.Children = new[] { new DrawableFlag(value.Country?.FlagName ?? @"__") { RelativeSizeAxes = Axes.Both } };
}
}
public IEnumerable<User> Participants
{
set
{
var ranks = value.Select(u => u.GlobalRank);
levelRangeLower.Text = ranks.Min().ToString();
levelRangeHigher.Text = ranks.Max().ToString();
}
}
public ParticipantInfo(string rankPrefix = null)
{
RelativeSizeAxes = Axes.X;
Height = 15f;
Children = new Drawable[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5f, 0f),
Children = new Drawable[]
{
flagContainer = new Container
{
Width = 22f,
RelativeSizeAxes = Axes.Y,
},
new Container //todo: team banners
{
Width = 38f,
RelativeSizeAxes = Axes.Y,
CornerRadius = 2f,
Masking = true,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"ad387e"),
},
},
},
new OsuSpriteText
{
Text = "hosted by",
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = 14,
},
host = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = 14,
Font = @"Exo2.0-BoldItalic",
},
},
},
levelRangeContainer = new FillFlowContainer
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Children = new[]
{
new OsuSpriteText
{
Text = rankPrefix,
TextSize = 14,
},
new OsuSpriteText
{
Text = "#",
TextSize = 14,
},
levelRangeLower = new OsuSpriteText
{
TextSize = 14,
Font = @"Exo2.0-Bold",
},
new OsuSpriteText
{
Text = " - ",
TextSize = 14,
},
new OsuSpriteText
{
Text = "#",
TextSize = 14,
},
levelRangeHigher = new OsuSpriteText
{
TextSize = 14,
Font = @"Exo2.0-Bold",
},
},
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
levelRangeContainer.Colour = colours.Gray9;
host.Colour = colours.Blue;
}
}
}

View File

@ -12,8 +12,6 @@ using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Beatmaps.Drawables; using osu.Game.Beatmaps.Drawables;
using osu.Game.Database; using osu.Game.Database;
@ -29,12 +27,13 @@ namespace osu.Game.Screens.Multiplayer
{ {
private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 };
private const float transition_duration = 100; private const float transition_duration = 100;
private const float ruleset_height = 30;
private readonly Box statusStrip; private readonly Box statusStrip;
private readonly Container coverContainer, rulesetContainer, gameTypeContainer, flagContainer; private readonly Container coverContainer;
private readonly FillFlowContainer topFlow, levelRangeContainer, participantsFlow; private readonly FillFlowContainer topFlow, participantsFlow;
private readonly OsuSpriteText participants, participantsSlash, maxParticipants, name, status, beatmapTitle, beatmapDash, beatmapArtist, beatmapAuthor, host, levelRangeLower, levelRangeHigher; private readonly ModeTypeInfo modeTypeInfo;
private readonly OsuSpriteText participants, participantsSlash, maxParticipants, name, status, beatmapTitle, beatmapDash, beatmapArtist, beatmapAuthor;
private readonly ParticipantInfo participantInfo;
private readonly ScrollContainer participantsScroll; private readonly ScrollContainer participantsScroll;
private readonly Bindable<string> nameBind = new Bindable<string>(); private readonly Bindable<string> nameBind = new Bindable<string>();
@ -191,20 +190,13 @@ namespace osu.Game.Screens.Multiplayer
new FillFlowContainer new FillFlowContainer
{ {
AutoSizeAxes = Axes.X, AutoSizeAxes = Axes.X,
Height = ruleset_height, Height = 30,
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
LayoutDuration = transition_duration, LayoutDuration = transition_duration,
Spacing = new Vector2(5f, 0f), Spacing = new Vector2(5f, 0f),
Children = new Drawable[] Children = new Drawable[]
{ {
rulesetContainer = new Container modeTypeInfo = new ModeTypeInfo(),
{
AutoSizeAxes = Axes.Both,
},
gameTypeContainer = new Container
{
AutoSizeAxes = Axes.Both,
},
new Container new Container
{ {
AutoSizeAxes = Axes.X, AutoSizeAxes = Axes.X,
@ -253,91 +245,7 @@ namespace osu.Game.Screens.Multiplayer
Padding = contentPadding, Padding = contentPadding,
Children = new Drawable[] Children = new Drawable[]
{ {
new FillFlowContainer participantInfo = new ParticipantInfo(@"Rank Range "),
{
AutoSizeAxes = Axes.X,
Height = 15f,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5f, 0f),
Children = new Drawable[]
{
flagContainer = new Container
{
Width = 22f,
RelativeSizeAxes = Axes.Y,
},
new Container //todo: team banners
{
Width = 38f,
RelativeSizeAxes = Axes.Y,
CornerRadius = 2f,
Masking = true,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"ad387e"),
},
},
},
new OsuSpriteText
{
Text = "hosted by",
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = 14,
},
host = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = 14,
Font = @"Exo2.0-BoldItalic",
},
},
},
levelRangeContainer = new FillFlowContainer
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Children = new[]
{
new OsuSpriteText
{
Text = "Rank Range ",
TextSize = 14,
},
new OsuSpriteText
{
Text = "#",
TextSize = 14,
},
levelRangeLower = new OsuSpriteText
{
TextSize = 14,
Font = @"Exo2.0-Bold",
},
new OsuSpriteText
{
Text = " - ",
TextSize = 14,
},
new OsuSpriteText
{
Text = "#",
TextSize = 14,
},
levelRangeHigher = new OsuSpriteText
{
Text = "6251",
TextSize = 14,
Font = @"Exo2.0-Bold",
},
},
},
}, },
}, },
}, },
@ -363,6 +271,7 @@ namespace osu.Game.Screens.Multiplayer
nameBind.ValueChanged += displayName; nameBind.ValueChanged += displayName;
hostBind.ValueChanged += displayUser; hostBind.ValueChanged += displayUser;
typeBind.ValueChanged += displayGameType;
maxParticipantsBind.ValueChanged += displayMaxParticipants; maxParticipantsBind.ValueChanged += displayMaxParticipants;
participantsBind.ValueChanged += displayParticipants; participantsBind.ValueChanged += displayParticipants;
} }
@ -373,16 +282,13 @@ namespace osu.Game.Screens.Multiplayer
this.localisation = localisation; this.localisation = localisation;
this.colours = colours; this.colours = colours;
beatmapAuthor.Colour = levelRangeContainer.Colour = colours.Gray9; beatmapAuthor.Colour = colours.Gray9;
host.Colour = colours.Blue;
//binded here instead of ctor because dependencies are needed //binded here instead of ctor because dependencies are needed
statusBind.ValueChanged += displayStatus; statusBind.ValueChanged += displayStatus;
typeBind.ValueChanged += displayGameType;
beatmapBind.ValueChanged += displayBeatmap; beatmapBind.ValueChanged += displayBeatmap;
statusBind.TriggerChange(); statusBind.TriggerChange();
typeBind.TriggerChange();
beatmapBind.TriggerChange(); beatmapBind.TriggerChange();
} }
@ -400,14 +306,7 @@ namespace osu.Game.Screens.Multiplayer
private void displayUser(User value) private void displayUser(User value)
{ {
host.Text = value.Username; participantInfo.Host = value;
flagContainer.Children = new[]
{
new DrawableFlag(value.Country?.FlagName ?? @"__")
{
RelativeSizeAxes = Axes.Both,
},
};
} }
private void displayStatus(RoomStatus value) private void displayStatus(RoomStatus value)
@ -420,39 +319,26 @@ namespace osu.Game.Screens.Multiplayer
private void displayGameType(GameType value) private void displayGameType(GameType value)
{ {
gameTypeContainer.Children = new[] modeTypeInfo.Type = value;
{
new DrawableGameType(value)
{
Size = new Vector2(ruleset_height),
},
};
} }
private void displayBeatmap(BeatmapInfo value) private void displayBeatmap(BeatmapInfo value)
{ {
modeTypeInfo.Beatmap = value;
if (value != null) if (value != null)
{ {
coverContainer.FadeIn(transition_duration); coverContainer.FadeIn(transition_duration);
coverContainer.Children = new[] coverContainer.Children = new[]
{ {
new AsyncLoadWrapper(new CoverSprite(value.BeatmapSet) new AsyncLoadWrapper(new BeatmapSetCover(value.BeatmapSet)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
FillMode = FillMode.Fill, FillMode = FillMode.Fill,
OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out), OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out),
}) { RelativeSizeAxes = Axes.Both } }) { RelativeSizeAxes = Axes.Both },
};
rulesetContainer.FadeIn(transition_duration);
rulesetContainer.Children = new[]
{
new DifficultyIcon(value)
{
Size = new Vector2(ruleset_height),
}
}; };
beatmapTitle.Current = localisation.GetUnicodePreference(value.Metadata.TitleUnicode, value.Metadata.Title); beatmapTitle.Current = localisation.GetUnicodePreference(value.Metadata.TitleUnicode, value.Metadata.Title);
@ -463,7 +349,6 @@ namespace osu.Game.Screens.Multiplayer
else else
{ {
coverContainer.FadeOut(transition_duration); coverContainer.FadeOut(transition_duration);
rulesetContainer.FadeOut(transition_duration);
beatmapTitle.Current = null; beatmapTitle.Current = null;
beatmapArtist.Current = null; beatmapArtist.Current = null;
@ -491,11 +376,7 @@ namespace osu.Game.Screens.Multiplayer
private void displayParticipants(User[] value) private void displayParticipants(User[] value)
{ {
participants.Text = value.Length.ToString(); participants.Text = value.Length.ToString();
participantInfo.Participants = value;
var ranks = value.Select(u => u.GlobalRank);
levelRangeLower.Text = ranks.Min().ToString();
levelRangeHigher.Text = ranks.Max().ToString();
participantsFlow.ChildrenEnumerable = value.Select(u => new UserTile(u)); participantsFlow.ChildrenEnumerable = value.Select(u => new UserTile(u));
} }
@ -527,22 +408,5 @@ namespace osu.Game.Screens.Multiplayer
}; };
} }
} }
private class CoverSprite : Sprite
{
private readonly BeatmapSetInfo set;
public CoverSprite(BeatmapSetInfo set)
{
this.set = set;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
if (set.OnlineInfo?.Covers?.Cover != null)
Texture = textures.Get(set.OnlineInfo.Covers.Cover);
}
}
} }
} }

View File

@ -12,16 +12,20 @@ using osu.Game.Rulesets.UI;
using OpenTK; using OpenTK;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using System.Linq;
namespace osu.Game.Screens.Play.HUD namespace osu.Game.Screens.Play.HUD
{ {
public class ModDisplay : Container, IHasCurrentValue<IEnumerable<Mod>> public class ModDisplay : Container, IHasCurrentValue<IEnumerable<Mod>>
{ {
private const int fade_duration = 1000;
private readonly Bindable<IEnumerable<Mod>> mods = new Bindable<IEnumerable<Mod>>(); private readonly Bindable<IEnumerable<Mod>> mods = new Bindable<IEnumerable<Mod>>();
public Bindable<IEnumerable<Mod>> Current => mods; public Bindable<IEnumerable<Mod>> Current => mods;
private readonly FillFlowContainer<ModIcon> iconsContainer; private readonly FillFlowContainer<ModIcon> iconsContainer;
private readonly OsuSpriteText unrankedText;
public ModDisplay() public ModDisplay()
{ {
@ -35,8 +39,9 @@ namespace osu.Game.Screens.Play.HUD
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
Margin = new MarginPadding { Left = 10, Right = 10 }, Margin = new MarginPadding { Left = 10, Right = 10 },
}, },
new OsuSpriteText unrankedText = new OsuSpriteText
{ {
AlwaysPresent = true,
Anchor = Anchor.BottomCentre, Anchor = Anchor.BottomCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
Text = @"/ UNRANKED /", Text = @"/ UNRANKED /",
@ -70,8 +75,13 @@ namespace osu.Game.Screens.Play.HUD
private void appearTransform() private void appearTransform()
{ {
if (mods.Value.Any(m => !m.Ranked))
unrankedText.FadeInFromZero(fade_duration, EasingTypes.OutQuint);
else
unrankedText.Hide();
iconsContainer.Flush(); iconsContainer.Flush();
iconsContainer.FadeInFromZero(1000, EasingTypes.OutQuint); iconsContainer.FadeInFromZero(fade_duration, EasingTypes.OutQuint);
expand(); expand();
using (iconsContainer.BeginDelayedSequence(1200)) using (iconsContainer.BeginDelayedSequence(1200))
contract(); contract();

View File

@ -277,9 +277,19 @@ namespace osu.Game.Screens.Play
protected override bool OnClick(InputState state) protected override bool OnClick(InputState state)
{ {
if (!Enabled)
return false;
box.FlashColour(Color4.White, 500, EasingTypes.OutQuint); box.FlashColour(Color4.White, 500, EasingTypes.OutQuint);
aspect.ScaleTo(1.2f, 2000, EasingTypes.OutQuint); aspect.ScaleTo(1.2f, 2000, EasingTypes.OutQuint);
return base.OnClick(state);
bool result = base.OnClick(state);
// for now, let's disable the skip button after the first press.
// this will likely need to be contextual in the future (bound from external components).
Enabled.Value = false;
return result;
} }
} }
} }

13
osu.Game/Users/Medal.cs Normal file
View File

@ -0,0 +1,13 @@
// 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 Medal
{
public string Name { get; set; }
public string InternalName { get; set; }
public string ImageUrl => $@"https://s.ppy.sh/images/medals-client/{InternalName}@2x.png";
public string Description { get; set; }
}
}

View File

@ -490,9 +490,15 @@
<Compile Include="Overlays\SearchableList\SlimEnumDropdown.cs" /> <Compile Include="Overlays\SearchableList\SlimEnumDropdown.cs" />
<Compile Include="Overlays\SearchableList\DisplayStyleControl.cs" /> <Compile Include="Overlays\SearchableList\DisplayStyleControl.cs" />
<Compile Include="Graphics\UserInterface\BreadcrumbControl.cs" /> <Compile Include="Graphics\UserInterface\BreadcrumbControl.cs" />
<Compile Include="Overlays\MedalOverlay.cs" />
<Compile Include="Users\Medal.cs" />
<Compile Include="Overlays\MedalSplash\DrawableMedal.cs" />
<Compile Include="Screens\Multiplayer\RoomInspector.cs" /> <Compile Include="Screens\Multiplayer\RoomInspector.cs" />
<Compile Include="Online\Multiplayer\GameType.cs" /> <Compile Include="Online\Multiplayer\GameType.cs" />
<Compile Include="Screens\Multiplayer\DrawableGameType.cs" /> <Compile Include="Screens\Multiplayer\DrawableGameType.cs" />
<Compile Include="Screens\Multiplayer\ParticipantInfo.cs" />
<Compile Include="Screens\Multiplayer\ModeTypeInfo.cs" />
<Compile Include="Beatmaps\Drawables\BeatmapSetCover.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj"> <ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">