mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 16:03:01 +08:00
Merge remote-tracking branch 'refs/remotes/Tom94/song-select-wedged-box'
# Conflicts: # osu-framework
This commit is contained in:
commit
ac8c180168
@ -1 +1 @@
|
|||||||
Subproject commit 37d53e32e58104c8e743efad855019c39edeb6b2
|
Subproject commit 9ed3a191bf76ead6ff34ac468898a0119b8e5454
|
@ -27,16 +27,12 @@ namespace osu.Desktop.VisualTests.Tests
|
|||||||
|
|
||||||
public override string Description => @"Showing hitobjects and what not.";
|
public override string Description => @"Showing hitobjects and what not.";
|
||||||
|
|
||||||
FramedClock localClock;
|
|
||||||
|
|
||||||
protected override IFrameBasedClock Clock => localClock;
|
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
base.Reset();
|
base.Reset();
|
||||||
|
|
||||||
//ensure we are at offset 0
|
//ensure we are at offset 0
|
||||||
localClock = new FramedClock();
|
Clock = new FramedClock();
|
||||||
|
|
||||||
List<HitObject> objects = new List<HitObject>();
|
List<HitObject> objects = new List<HitObject>();
|
||||||
|
|
||||||
@ -93,7 +89,7 @@ namespace osu.Desktop.VisualTests.Tests
|
|||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
localClock.ProcessFrame();
|
Clock.ProcessFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,21 +19,17 @@ namespace osu.Desktop.VisualTests.Tests
|
|||||||
{
|
{
|
||||||
public override string Name => @"Hit Objects";
|
public override string Name => @"Hit Objects";
|
||||||
|
|
||||||
IFrameBasedClock ourClock;
|
|
||||||
|
|
||||||
protected override IFrameBasedClock Clock => ourClock;
|
|
||||||
|
|
||||||
public TestCaseHitObjects()
|
public TestCaseHitObjects()
|
||||||
{
|
{
|
||||||
var swClock = new StopwatchClock(true) { Rate = 1 };
|
var swClock = new StopwatchClock(true) { Rate = 1 };
|
||||||
ourClock = new FramedClock(swClock);
|
Clock = new FramedClock(swClock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
base.Reset();
|
base.Reset();
|
||||||
|
|
||||||
ourClock.ProcessFrame();
|
Clock.ProcessFrame();
|
||||||
|
|
||||||
Container approachContainer = new Container { Depth = float.MaxValue, };
|
Container approachContainer = new Container { Depth = float.MaxValue, };
|
||||||
|
|
||||||
@ -45,7 +41,7 @@ namespace osu.Desktop.VisualTests.Tests
|
|||||||
{
|
{
|
||||||
var h = new HitCircle
|
var h = new HitCircle
|
||||||
{
|
{
|
||||||
StartTime = ourClock.CurrentTime + 1000 + i * 80,
|
StartTime = Clock.CurrentTime + 1000 + i * 80,
|
||||||
Position = new Vector2((i - count / 2) * 14),
|
Position = new Vector2((i - count / 2) * 14),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -65,7 +61,7 @@ namespace osu.Desktop.VisualTests.Tests
|
|||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
ourClock.ProcessFrame();
|
Clock.ProcessFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,20 +13,17 @@ namespace osu.Desktop.VisualTests.Tests
|
|||||||
public override string Name => @"Music Controller";
|
public override string Name => @"Music Controller";
|
||||||
public override string Description => @"Tests music controller ui.";
|
public override string Description => @"Tests music controller ui.";
|
||||||
|
|
||||||
IFrameBasedClock ourClock;
|
|
||||||
protected override IFrameBasedClock Clock => ourClock;
|
|
||||||
|
|
||||||
protected MusicController mc;
|
protected MusicController mc;
|
||||||
|
|
||||||
public TestCaseMusicController()
|
public TestCaseMusicController()
|
||||||
{
|
{
|
||||||
ourClock = new FramedClock();
|
Clock = new FramedClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
base.Reset();
|
base.Reset();
|
||||||
ourClock.ProcessFrame();
|
Clock.ProcessFrame();
|
||||||
mc = new MusicController
|
mc = new MusicController
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -39,7 +36,7 @@ namespace osu.Desktop.VisualTests.Tests
|
|||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
ourClock.ProcessFrame();
|
Clock.ProcessFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ using osu.Desktop.VisualTests.Platform;
|
|||||||
using osu.Framework.GameModes.Testing;
|
using osu.Framework.GameModes.Testing;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Modes;
|
using osu.Game.Modes;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Select;
|
||||||
|
|
||||||
namespace osu.Desktop.VisualTests.Tests
|
namespace osu.Desktop.VisualTests.Tests
|
||||||
{
|
{
|
||||||
|
@ -8,8 +8,6 @@ using osu.Framework.Timing;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Modes.Objects;
|
using osu.Game.Modes.Objects;
|
||||||
using osu.Game.Modes.Osu.Objects;
|
using osu.Game.Modes.Osu.Objects;
|
||||||
@ -24,16 +22,12 @@ namespace osu.Desktop.VisualTests.Tests
|
|||||||
|
|
||||||
public override string Description => @"Showing everything to play the game.";
|
public override string Description => @"Showing everything to play the game.";
|
||||||
|
|
||||||
FramedClock localClock;
|
|
||||||
|
|
||||||
protected override IFrameBasedClock Clock => localClock;
|
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
base.Reset();
|
base.Reset();
|
||||||
|
|
||||||
//ensure we are at offset 0
|
//ensure we are at offset 0
|
||||||
localClock = new FramedClock();
|
Clock = new FramedClock();
|
||||||
|
|
||||||
var objects = new List<HitObject>();
|
var objects = new List<HitObject>();
|
||||||
|
|
||||||
@ -75,7 +69,7 @@ namespace osu.Desktop.VisualTests.Tests
|
|||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
localClock.ProcessFrame();
|
Clock.ProcessFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ using osu.Framework.Allocation;
|
|||||||
|
|
||||||
namespace osu.Game.Beatmaps.Drawable
|
namespace osu.Game.Beatmaps.Drawable
|
||||||
{
|
{
|
||||||
class BeatmapGroup : Container, IStateful<BeatmapGroupState>
|
class BeatmapGroup : IStateful<BeatmapGroupState>
|
||||||
{
|
{
|
||||||
public BeatmapPanel SelectedPanel;
|
public BeatmapPanel SelectedPanel;
|
||||||
|
|
||||||
@ -27,8 +27,7 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
public Action<BeatmapGroup, BeatmapInfo> SelectionChanged;
|
public Action<BeatmapGroup, BeatmapInfo> SelectionChanged;
|
||||||
|
|
||||||
private BeatmapSetInfo beatmapSet;
|
private BeatmapSetInfo beatmapSet;
|
||||||
private BeatmapSetHeader header;
|
public BeatmapSetHeader Header;
|
||||||
private FlowContainer difficulties;
|
|
||||||
|
|
||||||
private BeatmapGroupState state;
|
private BeatmapGroupState state;
|
||||||
|
|
||||||
@ -43,24 +42,24 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case BeatmapGroupState.Expanded:
|
case BeatmapGroupState.Expanded:
|
||||||
FadeTo(1, 250);
|
|
||||||
|
|
||||||
//if (!difficulties.Children.All(d => IsLoaded))
|
//if (!difficulties.Children.All(d => IsLoaded))
|
||||||
// Task.WhenAll(difficulties.Children.Select(d => d.Preload(Game))).ContinueWith(t => difficulties.Show());
|
// Task.WhenAll(difficulties.Children.Select(d => d.Preload(Game))).ContinueWith(t => difficulties.Show());
|
||||||
//else
|
//else
|
||||||
difficulties.Show();
|
foreach (BeatmapPanel panel in BeatmapPanels)
|
||||||
|
panel.Show();
|
||||||
|
|
||||||
header.State = PanelSelectedState.Selected;
|
Header.State = PanelSelectedState.Selected;
|
||||||
if (SelectedPanel != null)
|
if (SelectedPanel != null)
|
||||||
SelectedPanel.State = PanelSelectedState.Selected;
|
SelectedPanel.State = PanelSelectedState.Selected;
|
||||||
break;
|
break;
|
||||||
case BeatmapGroupState.Collapsed:
|
case BeatmapGroupState.Collapsed:
|
||||||
FadeTo(0.8f, 250);
|
Header.State = PanelSelectedState.NotSelected;
|
||||||
|
|
||||||
header.State = PanelSelectedState.NotSelected;
|
|
||||||
if (SelectedPanel != null)
|
if (SelectedPanel != null)
|
||||||
SelectedPanel.State = PanelSelectedState.NotSelected;
|
SelectedPanel.State = PanelSelectedState.NotSelected;
|
||||||
difficulties.Hide();
|
|
||||||
|
foreach (BeatmapPanel panel in BeatmapPanels)
|
||||||
|
panel.Hide();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,54 +69,21 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
{
|
{
|
||||||
this.beatmapSet = beatmapSet;
|
this.beatmapSet = beatmapSet;
|
||||||
|
|
||||||
Alpha = 0;
|
Header = new BeatmapSetHeader(beatmapSet, working)
|
||||||
AutoSizeAxes = Axes.Y;
|
|
||||||
RelativeSizeAxes = Axes.X;
|
|
||||||
|
|
||||||
Children = new[]
|
|
||||||
{
|
{
|
||||||
new FlowContainer
|
GainedSelection = headerGainedSelection,
|
||||||
{
|
RelativeSizeAxes = Axes.X,
|
||||||
RelativeSizeAxes = Axes.X,
|
Anchor = Anchor.TopRight,
|
||||||
AutoSizeAxes = Axes.Y,
|
Origin = Anchor.TopRight,
|
||||||
Direction = FlowDirection.VerticalOnly,
|
|
||||||
Children = new Framework.Graphics.Drawable[]
|
|
||||||
{
|
|
||||||
header = new BeatmapSetHeader(beatmapSet, working)
|
|
||||||
{
|
|
||||||
GainedSelection = headerGainedSelection,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Anchor = Anchor.TopRight,
|
|
||||||
Origin = Anchor.TopRight,
|
|
||||||
},
|
|
||||||
difficulties = new FlowContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Margin = new MarginPadding { Top = 5 },
|
|
||||||
Padding = new MarginPadding { Left = 75 },
|
|
||||||
Spacing = new Vector2(0, 5),
|
|
||||||
Direction = FlowDirection.VerticalOnly,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(BaseGame game)
|
|
||||||
{
|
|
||||||
BeatmapPanels = beatmapSet.Beatmaps.Select(b => new BeatmapPanel(b)
|
BeatmapPanels = beatmapSet.Beatmaps.Select(b => new BeatmapPanel(b)
|
||||||
{
|
{
|
||||||
GainedSelection = panelGainedSelection,
|
GainedSelection = panelGainedSelection,
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
//for the time being, let's completely load the difficulty panels in the background.
|
|
||||||
//this likely won't scale so well, but allows us to completely async the loading flow.
|
|
||||||
Task.WhenAll(BeatmapPanels.Select(panel => panel.Preload(game, p => difficulties.Add(panel)))).Wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void headerGainedSelection(BeatmapSetHeader panel)
|
private void headerGainedSelection(BeatmapSetHeader panel)
|
||||||
|
@ -11,12 +11,14 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps.Drawable
|
namespace osu.Game.Beatmaps.Drawable
|
||||||
{
|
{
|
||||||
class BeatmapPanel : Panel
|
class BeatmapPanel : Panel
|
||||||
{
|
{
|
||||||
public BeatmapInfo Beatmap;
|
public BeatmapInfo Beatmap;
|
||||||
|
private Sprite background;
|
||||||
|
|
||||||
public Action<BeatmapPanel> GainedSelection;
|
public Action<BeatmapPanel> GainedSelection;
|
||||||
|
|
||||||
@ -24,6 +26,17 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
{
|
{
|
||||||
base.Selected();
|
base.Selected();
|
||||||
GainedSelection?.Invoke(this);
|
GainedSelection?.Invoke(this);
|
||||||
|
|
||||||
|
background.ColourInfo = ColourInfo.GradientVertical(
|
||||||
|
new Color4(20, 43, 51, 255),
|
||||||
|
new Color4(40, 86, 102, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Deselected()
|
||||||
|
{
|
||||||
|
base.Deselected();
|
||||||
|
|
||||||
|
background.Colour = new Color4(20, 43, 51, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeatmapPanel(BeatmapInfo beatmap)
|
public BeatmapPanel(BeatmapInfo beatmap)
|
||||||
@ -33,11 +46,9 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
|
|
||||||
Children = new Framework.Graphics.Drawable[]
|
Children = new Framework.Graphics.Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
background = new Box
|
||||||
{
|
{
|
||||||
Colour = new Color4(40, 86, 102, 255), // TODO: gradient
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Size = Vector2.One,
|
|
||||||
},
|
},
|
||||||
new FlowContainer
|
new FlowContainer
|
||||||
{
|
{
|
||||||
|
@ -10,10 +10,10 @@ using osu.Game.Database;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps.Drawable
|
namespace osu.Game.Beatmaps.Drawable
|
||||||
{
|
{
|
||||||
@ -28,15 +28,13 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
protected override void Selected()
|
protected override void Selected()
|
||||||
{
|
{
|
||||||
base.Selected();
|
base.Selected();
|
||||||
|
|
||||||
Width = 1;
|
|
||||||
GainedSelection?.Invoke(this);
|
GainedSelection?.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Deselected()
|
protected override void Deselected()
|
||||||
{
|
{
|
||||||
base.Deselected();
|
base.Deselected();
|
||||||
Width = 0.8f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -66,36 +64,83 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
this.beatmapSet = beatmapSet;
|
this.beatmapSet = beatmapSet;
|
||||||
Children = new Framework.Graphics.Drawable[]
|
Children = new Framework.Graphics.Drawable[]
|
||||||
{
|
{
|
||||||
working.Background == null ? new Box{ RelativeSizeAxes = Axes.Both, Colour = new Color4(20, 20, 20, 255) } : new Sprite
|
new BufferedContainer
|
||||||
{
|
{
|
||||||
Texture = working.Background,
|
CacheDrawnFrameBuffer = true,
|
||||||
Anchor = Anchor.Centre,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Origin = Anchor.Centre,
|
Children = new Framework.Graphics.Drawable[]
|
||||||
Scale = new Vector2(1366 / working.Background.Width * 0.6f),
|
{
|
||||||
Colour = new Color4(200, 200, 200, 255),
|
working.Background == null ? new Box{ RelativeSizeAxes = Axes.Both, Colour = new Color4(200, 200, 200, 255) } : new Sprite
|
||||||
|
{
|
||||||
|
Texture = working.Background,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Scale = new Vector2(1366 / working.Background.Width * 0.6f),
|
||||||
|
},
|
||||||
|
new FlowContainer
|
||||||
|
{
|
||||||
|
Direction = FlowDirection.HorizontalOnly,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
// This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle
|
||||||
|
Shear = new Vector2(0.8f, 0),
|
||||||
|
Alpha = 0.5f,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
// The left half with no gradient applied
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
Width = 0.4f,
|
||||||
|
},
|
||||||
|
// Piecewise-linear gradient with 3 segments to make it appear smoother
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
ColourInfo = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)),
|
||||||
|
Width = 0.05f,
|
||||||
|
},
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)),
|
||||||
|
Width = 0.2f,
|
||||||
|
},
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)),
|
||||||
|
Width = 0.05f,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
new FlowContainer
|
new FlowContainer
|
||||||
{
|
{
|
||||||
Direction = FlowDirection.VerticalOnly,
|
Direction = FlowDirection.VerticalOnly,
|
||||||
Spacing = new Vector2(0, 2),
|
Padding = new MarginPadding { Top = 5, Left = 18, Right = 10, Bottom = 10 },
|
||||||
Padding = new MarginPadding { Top = 10, Left = 15, Right = 10, Bottom = 10 },
|
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
title = new SpriteText
|
title = new SpriteText
|
||||||
{
|
{
|
||||||
Font = @"Exo2.0-SemiBoldItalic",
|
Font = @"Exo2.0-BoldItalic",
|
||||||
Text = beatmapSet.Metadata.Title,
|
Text = beatmapSet.Metadata.Title,
|
||||||
TextSize = 22
|
TextSize = 22,
|
||||||
|
Shadow = true,
|
||||||
},
|
},
|
||||||
artist = new SpriteText
|
artist = new SpriteText
|
||||||
{
|
{
|
||||||
Font = @"Exo2.0-MediumItalic",
|
Margin = new MarginPadding { Top = -1 },
|
||||||
|
Font = @"Exo2.0-SemiBoldItalic",
|
||||||
Text = beatmapSet.Metadata.Artist,
|
Text = beatmapSet.Metadata.Artist,
|
||||||
TextSize = 16
|
TextSize = 17,
|
||||||
|
Shadow = true,
|
||||||
},
|
},
|
||||||
new FlowContainer
|
new FlowContainer
|
||||||
{
|
{
|
||||||
|
Margin = new MarginPadding { Top = 5 },
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
@ -106,8 +151,6 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Deselected();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -26,8 +26,26 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
BorderColour = new Color4(221, 255, 255, 255);
|
BorderColour = new Color4(221, 255, 255, 255);
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
}
|
||||||
|
|
||||||
Deselected();
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
applyState();
|
||||||
|
FadeInFromZero(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyState()
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case PanelSelectedState.NotSelected:
|
||||||
|
Deselected();
|
||||||
|
break;
|
||||||
|
case PanelSelectedState.Selected:
|
||||||
|
Selected();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PanelSelectedState state = PanelSelectedState.NotSelected;
|
private PanelSelectedState state = PanelSelectedState.NotSelected;
|
||||||
@ -41,15 +59,7 @@ namespace osu.Game.Beatmaps.Drawable
|
|||||||
if (state == value) return;
|
if (state == value) return;
|
||||||
state = value;
|
state = value;
|
||||||
|
|
||||||
switch (state)
|
applyState();
|
||||||
{
|
|
||||||
case PanelSelectedState.NotSelected:
|
|
||||||
Deselected();
|
|
||||||
break;
|
|
||||||
case PanelSelectedState.Selected:
|
|
||||||
Selected();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
{
|
{
|
||||||
oldBackground.Depth = 1;
|
oldBackground.Depth = 1;
|
||||||
oldBackground.Flush();
|
oldBackground.Flush();
|
||||||
oldBackground.FadeOut(500);
|
oldBackground.FadeOut(250);
|
||||||
oldBackground.Expire();
|
oldBackground.Expire();
|
||||||
|
|
||||||
background.BlurSigma = oldBackground.BlurSigma;
|
background.BlurSigma = oldBackground.BlurSigma;
|
||||||
@ -63,11 +63,6 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
background?.BlurTo(sigma, duration, EasingTypes.OutExpo);
|
background?.BlurTo(sigma, duration, EasingTypes.OutExpo);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(BackgroundMode other)
|
public override bool Equals(BackgroundMode other)
|
||||||
{
|
{
|
||||||
return base.Equals(other) && beatmap == ((BackgroundModeBeatmap)other).Beatmap;
|
return base.Equals(other) && beatmap == ((BackgroundModeBeatmap)other).Beatmap;
|
||||||
|
@ -15,6 +15,7 @@ using osu.Game.Screens.Edit;
|
|||||||
using osu.Game.Screens.Multiplayer;
|
using osu.Game.Screens.Multiplayer;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
using osu.Game.Screens.Select;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Menu
|
namespace osu.Game.Screens.Menu
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ using osu.Framework.GameModes;
|
|||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using osu.Game.Screens.Select;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Multiplayer
|
namespace osu.Game.Screens.Multiplayer
|
||||||
{
|
{
|
||||||
|
@ -1,300 +0,0 @@
|
|||||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Audio;
|
|
||||||
using osu.Framework.Audio.Track;
|
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.GameModes;
|
|
||||||
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.Beatmaps;
|
|
||||||
using osu.Game.Beatmaps.Drawable;
|
|
||||||
using osu.Game.Database;
|
|
||||||
using osu.Game.Modes;
|
|
||||||
using osu.Game.Screens.Backgrounds;
|
|
||||||
using OpenTK;
|
|
||||||
using OpenTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
|
||||||
{
|
|
||||||
public class PlaySongSelect : OsuGameMode
|
|
||||||
{
|
|
||||||
private Bindable<PlayMode> playMode;
|
|
||||||
private BeatmapDatabase database;
|
|
||||||
private BeatmapGroup selectedBeatmapGroup;
|
|
||||||
private BeatmapInfo selectedBeatmapInfo;
|
|
||||||
|
|
||||||
protected override BackgroundMode CreateBackground() => new BackgroundModeBeatmap(Beatmap);
|
|
||||||
|
|
||||||
private ScrollContainer scrollContainer;
|
|
||||||
private FlowContainer beatmapSetFlow;
|
|
||||||
private TrackManager trackManager;
|
|
||||||
private Container wedgeContainer;
|
|
||||||
|
|
||||||
private static readonly Vector2 BACKGROUND_BLUR = new Vector2(20);
|
|
||||||
|
|
||||||
/// <param name="database">Optionally provide a database to use instead of the OsuGame one.</param>
|
|
||||||
public PlaySongSelect(BeatmapDatabase database = null)
|
|
||||||
{
|
|
||||||
this.database = database;
|
|
||||||
|
|
||||||
const float scrollWidth = 640;
|
|
||||||
const float bottomToolHeight = 50;
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
wedgeContainer = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Size = Vector2.One,
|
|
||||||
Padding = new MarginPadding { Right = scrollWidth - 200 },
|
|
||||||
Children = new[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Size = new Vector2(1, 0.5f),
|
|
||||||
Colour = new Color4(0, 0, 0, 0.5f),
|
|
||||||
Shear = new Vector2(0.15f, 0),
|
|
||||||
EdgeSmoothness = new Vector2(2, 0),
|
|
||||||
},
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
RelativePositionAxes = Axes.Y,
|
|
||||||
Size = new Vector2(1, -0.5f),
|
|
||||||
Position = new Vector2(0, 1),
|
|
||||||
Colour = new Color4(0, 0, 0, 0.5f),
|
|
||||||
Shear = new Vector2(-0.15f, 0),
|
|
||||||
EdgeSmoothness = new Vector2(2, 0),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scrollContainer = new ScrollContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Size = new Vector2(scrollWidth, 1),
|
|
||||||
Anchor = Anchor.CentreRight,
|
|
||||||
Origin = Anchor.CentreRight,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
beatmapSetFlow = new FlowContainer
|
|
||||||
{
|
|
||||||
Padding = new MarginPadding { Left = 25, Top = 25, Bottom = 25 + bottomToolHeight },
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Direction = FlowDirection.VerticalOnly,
|
|
||||||
Spacing = new Vector2(0, 5),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Height = bottomToolHeight,
|
|
||||||
Anchor = Anchor.BottomCentre,
|
|
||||||
Origin = Anchor.BottomCentre,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Size = Vector2.One,
|
|
||||||
Colour = new Color4(0, 0, 0, 0.5f),
|
|
||||||
},
|
|
||||||
new Button
|
|
||||||
{
|
|
||||||
Anchor = Anchor.CentreRight,
|
|
||||||
Origin = Anchor.CentreRight,
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Width = 100,
|
|
||||||
Text = "Play",
|
|
||||||
Colour = new Color4(238, 51, 153, 255),
|
|
||||||
Action = () => Push(new Player
|
|
||||||
{
|
|
||||||
BeatmapInfo = selectedBeatmapGroup.SelectedPanel.Beatmap,
|
|
||||||
PreferredPlayMode = playMode.Value
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
|
||||||
private void load(BeatmapDatabase beatmaps, AudioManager audio, OsuGame game)
|
|
||||||
{
|
|
||||||
if (game != null)
|
|
||||||
{
|
|
||||||
playMode = game.PlayMode;
|
|
||||||
playMode.ValueChanged += playMode_ValueChanged;
|
|
||||||
// Temporary:
|
|
||||||
scrollContainer.Padding = new MarginPadding { Top = ToolbarPadding };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (database == null)
|
|
||||||
database = beatmaps;
|
|
||||||
|
|
||||||
database.BeatmapSetAdded += s => Schedule(() => addBeatmapSet(s));
|
|
||||||
|
|
||||||
trackManager = audio.Track;
|
|
||||||
|
|
||||||
Task.Factory.StartNew(addBeatmapSets);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnEntering(GameMode last)
|
|
||||||
{
|
|
||||||
base.OnEntering(last);
|
|
||||||
ensurePlayingSelected();
|
|
||||||
wedgeContainer.FadeInFromZero(250);
|
|
||||||
|
|
||||||
(Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnResuming(GameMode last)
|
|
||||||
{
|
|
||||||
(Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000);
|
|
||||||
|
|
||||||
ensurePlayingSelected();
|
|
||||||
base.OnResuming(last);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
|
||||||
{
|
|
||||||
base.Dispose(isDisposing);
|
|
||||||
if (playMode != null)
|
|
||||||
playMode.ValueChanged -= playMode_ValueChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playMode_ValueChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The global Beatmap was changed.
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnBeatmapChanged(WorkingBeatmap beatmap)
|
|
||||||
{
|
|
||||||
base.OnBeatmapChanged(beatmap);
|
|
||||||
|
|
||||||
var backgroundModeBeatmap = Background as BackgroundModeBeatmap;
|
|
||||||
if (backgroundModeBeatmap != null)
|
|
||||||
{
|
|
||||||
backgroundModeBeatmap.Beatmap = beatmap;
|
|
||||||
// TODO: Remove this once we have non-nullable Beatmap
|
|
||||||
(Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
selectBeatmap(beatmap.BeatmapInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectBeatmap(BeatmapInfo beatmap)
|
|
||||||
{
|
|
||||||
if (beatmap.Equals(selectedBeatmapInfo))
|
|
||||||
return;
|
|
||||||
|
|
||||||
//this is VERY temporary logic.
|
|
||||||
beatmapSetFlow.Children.Cast<BeatmapGroup>().Any(b =>
|
|
||||||
{
|
|
||||||
var panel = b.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(beatmap));
|
|
||||||
if (panel != null)
|
|
||||||
{
|
|
||||||
panel.State = PanelSelectedState.Selected;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// selection has been changed as the result of interaction with the carousel.
|
|
||||||
/// </summary>
|
|
||||||
private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap)
|
|
||||||
{
|
|
||||||
selectedBeatmapInfo = beatmap;
|
|
||||||
|
|
||||||
if (!beatmap.Equals(Beatmap?.BeatmapInfo))
|
|
||||||
{
|
|
||||||
Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
ensurePlayingSelected();
|
|
||||||
|
|
||||||
if (selectedBeatmapGroup == group)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (selectedBeatmapGroup != null)
|
|
||||||
selectedBeatmapGroup.State = BeatmapGroupState.Collapsed;
|
|
||||||
|
|
||||||
selectedBeatmapGroup = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ensurePlayingSelected()
|
|
||||||
{
|
|
||||||
AudioTrack track = null;
|
|
||||||
|
|
||||||
await Task.Run(() => track = Beatmap?.Track);
|
|
||||||
|
|
||||||
Schedule(delegate
|
|
||||||
{
|
|
||||||
if (track != null)
|
|
||||||
{
|
|
||||||
trackManager.SetExclusive(track);
|
|
||||||
track.Start();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addBeatmapSet(BeatmapSetInfo beatmapSet)
|
|
||||||
{
|
|
||||||
beatmapSet = database.GetWithChildren<BeatmapSetInfo>(beatmapSet.BeatmapSetID);
|
|
||||||
beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b));
|
|
||||||
beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList();
|
|
||||||
|
|
||||||
var working = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault());
|
|
||||||
|
|
||||||
var group = new BeatmapGroup(beatmapSet, working) { SelectionChanged = selectionChanged };
|
|
||||||
|
|
||||||
group.Preload(Game, g =>
|
|
||||||
{
|
|
||||||
beatmapSetFlow.Add(group);
|
|
||||||
|
|
||||||
if (Beatmap == null)
|
|
||||||
{
|
|
||||||
if (beatmapSetFlow.Children.Count() == 1)
|
|
||||||
{
|
|
||||||
group.State = BeatmapGroupState.Expanded;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (selectedBeatmapInfo?.Equals(Beatmap.BeatmapInfo) != true)
|
|
||||||
{
|
|
||||||
var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(Beatmap.BeatmapInfo));
|
|
||||||
if (panel != null)
|
|
||||||
{
|
|
||||||
panel.State = PanelSelectedState.Selected;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
group.State = BeatmapGroupState.Collapsed;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addBeatmapSets()
|
|
||||||
{
|
|
||||||
foreach (var beatmapSet in database.Query<BeatmapSetInfo>())
|
|
||||||
addBeatmapSet(beatmapSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -32,10 +32,7 @@ namespace osu.Game.Screens.Play
|
|||||||
public BeatmapInfo BeatmapInfo;
|
public BeatmapInfo BeatmapInfo;
|
||||||
|
|
||||||
public PlayMode PreferredPlayMode;
|
public PlayMode PreferredPlayMode;
|
||||||
|
|
||||||
protected override IFrameBasedClock Clock => playerClock;
|
|
||||||
|
|
||||||
private InterpolatingFramedClock playerClock;
|
|
||||||
private IAdjustableClock sourceClock;
|
private IAdjustableClock sourceClock;
|
||||||
|
|
||||||
private Ruleset ruleset;
|
private Ruleset ruleset;
|
||||||
@ -64,7 +61,7 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
|
|
||||||
sourceClock = (IAdjustableClock)track ?? new StopwatchClock();
|
sourceClock = (IAdjustableClock)track ?? new StopwatchClock();
|
||||||
playerClock = new InterpolatingFramedClock(sourceClock);
|
Clock = new InterpolatingFramedClock(sourceClock);
|
||||||
|
|
||||||
Schedule(() =>
|
Schedule(() =>
|
||||||
{
|
{
|
||||||
@ -118,7 +115,7 @@ namespace osu.Game.Screens.Play
|
|||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
playerClock.ProcessFrame();
|
Clock.ProcessFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlayerInputManager : UserInputManager
|
class PlayerInputManager : UserInputManager
|
||||||
|
124
osu.Game/Screens/Select/CarousellContainer.cs
Normal file
124
osu.Game/Screens/Select/CarousellContainer.cs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using OpenTK;
|
||||||
|
using osu.Framework.Caching;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Primitives;
|
||||||
|
using osu.Game.Beatmaps.Drawable;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select
|
||||||
|
{
|
||||||
|
class CarousellContainer : ScrollContainer
|
||||||
|
{
|
||||||
|
private Container<Panel> scrollableContent;
|
||||||
|
private List<BeatmapGroup> groups = new List<BeatmapGroup>();
|
||||||
|
public BeatmapGroup SelectedGroup { get; private set; }
|
||||||
|
|
||||||
|
private Cached yPositions = new Cached();
|
||||||
|
|
||||||
|
public CarousellContainer()
|
||||||
|
{
|
||||||
|
Add(scrollableContent = new Container<Panel>
|
||||||
|
{
|
||||||
|
Padding = new MarginPadding { Left = 25, Top = 25, Bottom = 25 },
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddGroup(BeatmapGroup group)
|
||||||
|
{
|
||||||
|
group.State = BeatmapGroupState.Collapsed;
|
||||||
|
|
||||||
|
groups.Add(group);
|
||||||
|
|
||||||
|
yPositions.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void computeYPositions()
|
||||||
|
{
|
||||||
|
float currentY = 0;
|
||||||
|
foreach (BeatmapGroup group in groups)
|
||||||
|
{
|
||||||
|
group.Header.Position = new Vector2(group.Header.Position.X, currentY);
|
||||||
|
currentY += group.Header.DrawSize.Y + 5;
|
||||||
|
|
||||||
|
if (group.State == BeatmapGroupState.Expanded)
|
||||||
|
{
|
||||||
|
foreach (BeatmapPanel panel in group.BeatmapPanels)
|
||||||
|
{
|
||||||
|
panel.Position = new Vector2(panel.Position.X, currentY);
|
||||||
|
currentY += panel.DrawSize.Y + 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectBeatmap(BeatmapInfo beatmap)
|
||||||
|
{
|
||||||
|
foreach (BeatmapGroup group in groups)
|
||||||
|
{
|
||||||
|
var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(beatmap));
|
||||||
|
if (panel != null)
|
||||||
|
SelectGroup(group, panel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectGroup(BeatmapGroup group, BeatmapPanel panel)
|
||||||
|
{
|
||||||
|
if (SelectedGroup != null && SelectedGroup != group)
|
||||||
|
SelectedGroup.State = BeatmapGroupState.Collapsed;
|
||||||
|
|
||||||
|
SelectedGroup = group;
|
||||||
|
panel.State = PanelSelectedState.Selected;
|
||||||
|
|
||||||
|
yPositions.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateLayout()
|
||||||
|
{
|
||||||
|
base.UpdateLayout();
|
||||||
|
|
||||||
|
if (!yPositions.EnsureValid())
|
||||||
|
yPositions.Refresh(computeYPositions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
scrollableContent.Clear(false);
|
||||||
|
|
||||||
|
foreach (BeatmapGroup group in groups)
|
||||||
|
{
|
||||||
|
scrollableContent.Add(group.Header);
|
||||||
|
|
||||||
|
if (group.State == BeatmapGroupState.Expanded)
|
||||||
|
foreach (BeatmapPanel panel in group.BeatmapPanels)
|
||||||
|
scrollableContent.Add(panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Panel panel in scrollableContent.Children)
|
||||||
|
{
|
||||||
|
if (panel.Position.Y < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vector2 panelPosLocal = panel.Position;
|
||||||
|
Vector2 panelPos = panel.ToSpaceOfOtherDrawable(panel.DrawSize / 2.0f, this);
|
||||||
|
|
||||||
|
float halfHeight = DrawSize.Y / 2;
|
||||||
|
float dist = Math.Abs(panelPos.Y - halfHeight);
|
||||||
|
panel.Position = new Vector2(
|
||||||
|
(panel is BeatmapSetHeader && panel.State == PanelSelectedState.Selected ? 0 : 100) + dist * 0.1f, panelPosLocal.Y);
|
||||||
|
|
||||||
|
panel.Alpha = MathHelper.Clamp(1.75f - 1.5f * dist / halfHeight, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
|
using osu.Game.Screens.Edit;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit
|
namespace osu.Game.Screens.Select
|
||||||
{
|
{
|
||||||
class EditSongSelect : GameModeWhiteBox
|
class EditSongSelect : GameModeWhiteBox
|
||||||
{
|
{
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Multiplayer
|
namespace osu.Game.Screens.Select
|
||||||
{
|
{
|
||||||
class MatchSongSelect : GameModeWhiteBox
|
class MatchSongSelect : GameModeWhiteBox
|
||||||
{
|
{
|
405
osu.Game/Screens/Select/PlaySongSelect.cs
Normal file
405
osu.Game/Screens/Select/PlaySongSelect.cs
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.GameModes;
|
||||||
|
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.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Drawable;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Modes;
|
||||||
|
using osu.Game.Screens.Backgrounds;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Framework;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select
|
||||||
|
{
|
||||||
|
public class PlaySongSelect : OsuGameMode
|
||||||
|
{
|
||||||
|
private Bindable<PlayMode> playMode;
|
||||||
|
private BeatmapDatabase database;
|
||||||
|
protected override BackgroundMode CreateBackground() => new BackgroundModeBeatmap(Beatmap);
|
||||||
|
|
||||||
|
private CarousellContainer carousell;
|
||||||
|
private TrackManager trackManager;
|
||||||
|
private Container backgroundWedgesContainer;
|
||||||
|
|
||||||
|
private static readonly Vector2 wedged_container_size = new Vector2(700, 225);
|
||||||
|
private static readonly Vector2 wedged_container_shear = new Vector2(0.15f, 0);
|
||||||
|
private static readonly Vector2 wedged_container_start_position = new Vector2(0, 50);
|
||||||
|
private Container wedgedContainer;
|
||||||
|
private Container wedgedBeatmapInfo;
|
||||||
|
|
||||||
|
private static readonly Vector2 BACKGROUND_BLUR = new Vector2(20);
|
||||||
|
|
||||||
|
/// <param name="database">Optionally provide a database to use instead of the OsuGame one.</param>
|
||||||
|
public PlaySongSelect(BeatmapDatabase database = null)
|
||||||
|
{
|
||||||
|
this.database = database;
|
||||||
|
|
||||||
|
const float scrollWidth = 640;
|
||||||
|
const float bottomToolHeight = 50;
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
backgroundWedgesContainer = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Size = Vector2.One,
|
||||||
|
Padding = new MarginPadding { Right = scrollWidth },
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Size = new Vector2(1, 0.5f),
|
||||||
|
Colour = new Color4(0, 0, 0, 0.5f),
|
||||||
|
Shear = new Vector2(0.15f, 0),
|
||||||
|
EdgeSmoothness = new Vector2(2, 0),
|
||||||
|
},
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
RelativePositionAxes = Axes.Y,
|
||||||
|
Size = new Vector2(1, -0.5f),
|
||||||
|
Position = new Vector2(0, 1),
|
||||||
|
Colour = new Color4(0, 0, 0, 0.5f),
|
||||||
|
Shear = new Vector2(-0.15f, 0),
|
||||||
|
EdgeSmoothness = new Vector2(2, 0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
carousell = new CarousellContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Size = new Vector2(scrollWidth, 1),
|
||||||
|
Anchor = Anchor.CentreRight,
|
||||||
|
Origin = Anchor.CentreRight,
|
||||||
|
},
|
||||||
|
wedgedContainer = new Container
|
||||||
|
{
|
||||||
|
Alpha = 0,
|
||||||
|
Position = wedged_container_start_position,
|
||||||
|
Size = wedged_container_size,
|
||||||
|
Margin = new MarginPadding { Top = 20, Right = 20, },
|
||||||
|
Masking = true,
|
||||||
|
BorderColour = new Color4(221, 255, 255, 255),
|
||||||
|
BorderThickness = 2.5f,
|
||||||
|
EdgeEffect = new EdgeEffect
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Glow,
|
||||||
|
Colour = new Color4(130, 204, 255, 150),
|
||||||
|
Radius = 20,
|
||||||
|
Roundness = 15,
|
||||||
|
},
|
||||||
|
Shear = wedged_container_shear,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = bottomToolHeight,
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Size = Vector2.One,
|
||||||
|
Colour = new Color4(0, 0, 0, 0.5f),
|
||||||
|
},
|
||||||
|
new Button
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreRight,
|
||||||
|
Origin = Anchor.CentreRight,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Width = 100,
|
||||||
|
Text = "Play",
|
||||||
|
Colour = new Color4(238, 51, 153, 255),
|
||||||
|
Action = () => Push(new Player
|
||||||
|
{
|
||||||
|
BeatmapInfo = carousell.SelectedGroup.SelectedPanel.Beatmap,
|
||||||
|
PreferredPlayMode = playMode.Value
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
|
private void load(BeatmapDatabase beatmaps, AudioManager audio, BaseGame game, OsuGame osuGame)
|
||||||
|
{
|
||||||
|
if (osuGame != null)
|
||||||
|
{
|
||||||
|
playMode = osuGame.PlayMode;
|
||||||
|
playMode.ValueChanged += playMode_ValueChanged;
|
||||||
|
// Temporary:
|
||||||
|
carousell.Padding = new MarginPadding { Top = ToolbarPadding };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (database == null)
|
||||||
|
database = beatmaps;
|
||||||
|
|
||||||
|
database.BeatmapSetAdded += s => Schedule(() => addBeatmapSet(s, game));
|
||||||
|
|
||||||
|
trackManager = audio.Track;
|
||||||
|
|
||||||
|
Task.Factory.StartNew(() => addBeatmapSets(game));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnEntering(GameMode last)
|
||||||
|
{
|
||||||
|
base.OnEntering(last);
|
||||||
|
ensurePlayingSelected();
|
||||||
|
|
||||||
|
changeBackground(Beatmap);
|
||||||
|
|
||||||
|
Content.FadeInFromZero(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnResuming(GameMode last)
|
||||||
|
{
|
||||||
|
changeBackground(Beatmap);
|
||||||
|
ensurePlayingSelected();
|
||||||
|
base.OnResuming(last);
|
||||||
|
|
||||||
|
Content.FadeIn(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnSuspending(GameMode next)
|
||||||
|
{
|
||||||
|
Content.FadeOut(250);
|
||||||
|
base.OnSuspending(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnExiting(GameMode next)
|
||||||
|
{
|
||||||
|
Content.FadeOut(100);
|
||||||
|
return base.OnExiting(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
if (playMode != null)
|
||||||
|
playMode.ValueChanged -= playMode_ValueChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playMode_ValueChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeBackground(WorkingBeatmap beatmap)
|
||||||
|
{
|
||||||
|
if (beatmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var backgroundModeBeatmap = Background as BackgroundModeBeatmap;
|
||||||
|
if (backgroundModeBeatmap != null)
|
||||||
|
{
|
||||||
|
backgroundModeBeatmap.Beatmap = beatmap;
|
||||||
|
// TODO: Remove this once we have non-nullable Beatmap
|
||||||
|
(Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshWedgedBeatmapInfo(beatmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshWedgedBeatmapInfo(WorkingBeatmap beatmap)
|
||||||
|
{
|
||||||
|
if (beatmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wedgedBeatmapInfo != null)
|
||||||
|
{
|
||||||
|
Drawable oldWedgedBeatmapInfo = wedgedBeatmapInfo;
|
||||||
|
oldWedgedBeatmapInfo.Depth = 1;
|
||||||
|
oldWedgedBeatmapInfo.FadeOut(250);
|
||||||
|
oldWedgedBeatmapInfo.Expire();
|
||||||
|
}
|
||||||
|
|
||||||
|
wedgedContainer.FadeIn(250);
|
||||||
|
|
||||||
|
BeatmapSetInfo beatmapSetInfo = beatmap.BeatmapSetInfo;
|
||||||
|
BeatmapInfo beatmapInfo = beatmap.BeatmapInfo;
|
||||||
|
wedgedContainer.Add(wedgedBeatmapInfo = new BufferedContainer
|
||||||
|
{
|
||||||
|
PixelSnapping = true,
|
||||||
|
CacheDrawnFrameBuffer = true,
|
||||||
|
Shear = -wedged_container_shear,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
// We will create the white-to-black gradient by modulating transparency and having
|
||||||
|
// a black backdrop. This results in an sRGB-space gradient and not linear space,
|
||||||
|
// transitioning from white to black more perceptually uniformly.
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
},
|
||||||
|
// We use a container, such that we can set the colour gradient to go across the
|
||||||
|
// vertices of the masked container instead of the vertices of the (larger) sprite.
|
||||||
|
beatmap.Background == null ? new Container() : new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
ColourInfo = ColourInfo.GradientVertical(Color4.White, new Color4(1f, 1f, 1f, 0.3f)),
|
||||||
|
Children = new []
|
||||||
|
{
|
||||||
|
// Zoomed-in and cropped beatmap background
|
||||||
|
new Sprite
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Texture = beatmap.Background,
|
||||||
|
Scale = new Vector2(1366 / beatmap.Background.Width * 0.6f),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Text for beatmap info
|
||||||
|
new FlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Direction = FlowDirection.VerticalOnly,
|
||||||
|
Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 40 },
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new SpriteText
|
||||||
|
{
|
||||||
|
Font = @"Exo2.0-MediumItalic",
|
||||||
|
Text = beatmapSetInfo.Metadata.Artist + " -- " + beatmapSetInfo.Metadata.Title,
|
||||||
|
TextSize = 28,
|
||||||
|
Shadow = true,
|
||||||
|
},
|
||||||
|
new SpriteText
|
||||||
|
{
|
||||||
|
Font = @"Exo2.0-MediumItalic",
|
||||||
|
Text = beatmapInfo.Version,
|
||||||
|
TextSize = 17,
|
||||||
|
Shadow = true,
|
||||||
|
},
|
||||||
|
new FlowContainer
|
||||||
|
{
|
||||||
|
Margin = new MarginPadding { Top = 10 },
|
||||||
|
Direction = FlowDirection.HorizontalOnly,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Children = new []
|
||||||
|
{
|
||||||
|
new SpriteText
|
||||||
|
{
|
||||||
|
Font = @"Exo2.0-Medium",
|
||||||
|
Text = "mapped by ",
|
||||||
|
TextSize = 15,
|
||||||
|
Shadow = true,
|
||||||
|
},
|
||||||
|
new SpriteText
|
||||||
|
{
|
||||||
|
Font = @"Exo2.0-Bold",
|
||||||
|
Text = beatmapSetInfo.Metadata.Author,
|
||||||
|
TextSize = 15,
|
||||||
|
Shadow = true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The global Beatmap was changed.
|
||||||
|
/// </summary>
|
||||||
|
protected override void OnBeatmapChanged(WorkingBeatmap beatmap)
|
||||||
|
{
|
||||||
|
base.OnBeatmapChanged(beatmap);
|
||||||
|
|
||||||
|
changeBackground(beatmap);
|
||||||
|
|
||||||
|
selectBeatmap(beatmap.BeatmapInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectBeatmap(BeatmapInfo beatmap)
|
||||||
|
{
|
||||||
|
carousell.SelectBeatmap(beatmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// selection has been changed as the result of interaction with the carousel.
|
||||||
|
/// </summary>
|
||||||
|
private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap)
|
||||||
|
{
|
||||||
|
if (!beatmap.Equals(Beatmap?.BeatmapInfo))
|
||||||
|
Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap);
|
||||||
|
|
||||||
|
ensurePlayingSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ensurePlayingSelected()
|
||||||
|
{
|
||||||
|
AudioTrack track = null;
|
||||||
|
|
||||||
|
await Task.Run(() => track = Beatmap?.Track);
|
||||||
|
|
||||||
|
Schedule(delegate
|
||||||
|
{
|
||||||
|
if (track != null)
|
||||||
|
{
|
||||||
|
trackManager.SetExclusive(track);
|
||||||
|
track.Start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBeatmapSet(BeatmapSetInfo beatmapSet, BaseGame game)
|
||||||
|
{
|
||||||
|
beatmapSet = database.GetWithChildren<BeatmapSetInfo>(beatmapSet.BeatmapSetID);
|
||||||
|
beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b));
|
||||||
|
beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList();
|
||||||
|
|
||||||
|
var working = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault());
|
||||||
|
|
||||||
|
var group = new BeatmapGroup(beatmapSet, working) { SelectionChanged = selectionChanged };
|
||||||
|
|
||||||
|
//for the time being, let's completely load the difficulty panels in the background.
|
||||||
|
//this likely won't scale so well, but allows us to completely async the loading flow.
|
||||||
|
Task.WhenAll(group.BeatmapPanels.Select(panel => panel.Preload(game))).ContinueWith(task => Schedule(delegate
|
||||||
|
{
|
||||||
|
carousell.AddGroup(group);
|
||||||
|
|
||||||
|
if (Beatmap == null)
|
||||||
|
carousell.SelectBeatmap(beatmapSet.Beatmaps.First());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(Beatmap.BeatmapInfo));
|
||||||
|
if (panel != null)
|
||||||
|
carousell.SelectGroup(group, panel);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBeatmapSets(BaseGame game)
|
||||||
|
{
|
||||||
|
foreach (var beatmapSet in database.Query<BeatmapSetInfo>())
|
||||||
|
addBeatmapSet(beatmapSet, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -103,7 +103,8 @@
|
|||||||
<Compile Include="Screens\Multiplayer\Lobby.cs" />
|
<Compile Include="Screens\Multiplayer\Lobby.cs" />
|
||||||
<Compile Include="Screens\Multiplayer\Match.cs" />
|
<Compile Include="Screens\Multiplayer\Match.cs" />
|
||||||
<Compile Include="Screens\Multiplayer\MatchCreate.cs" />
|
<Compile Include="Screens\Multiplayer\MatchCreate.cs" />
|
||||||
<Compile Include="Screens\Multiplayer\MatchSongSelect.cs" />
|
<Compile Include="Screens\Select\CarousellContainer.cs" />
|
||||||
|
<Compile Include="Screens\Select\MatchSongSelect.cs" />
|
||||||
<Compile Include="Screens\OsuGameMode.cs" />
|
<Compile Include="Screens\OsuGameMode.cs" />
|
||||||
<Compile Include="Screens\Play\ModSelect.cs" />
|
<Compile Include="Screens\Play\ModSelect.cs" />
|
||||||
<Compile Include="Beatmaps\Drawable\BeatmapGroup.cs" />
|
<Compile Include="Beatmaps\Drawable\BeatmapGroup.cs" />
|
||||||
@ -114,11 +115,11 @@
|
|||||||
<Compile Include="Modes\Ruleset.cs" />
|
<Compile Include="Modes\Ruleset.cs" />
|
||||||
<Compile Include="Screens\Ranking\Results.cs" />
|
<Compile Include="Screens\Ranking\Results.cs" />
|
||||||
<Compile Include="Screens\Direct\OnlineListing.cs" />
|
<Compile Include="Screens\Direct\OnlineListing.cs" />
|
||||||
<Compile Include="Screens\Play\PlaySongSelect.cs" />
|
<Compile Include="Screens\Select\PlaySongSelect.cs" />
|
||||||
<Compile Include="Modes\UI\HitRenderer.cs" />
|
<Compile Include="Modes\UI\HitRenderer.cs" />
|
||||||
<Compile Include="Modes\UI\Playfield.cs" />
|
<Compile Include="Modes\UI\Playfield.cs" />
|
||||||
<Compile Include="Modes\UI\ScoreOverlay.cs" />
|
<Compile Include="Modes\UI\ScoreOverlay.cs" />
|
||||||
<Compile Include="Screens\Edit\EditSongSelect.cs" />
|
<Compile Include="Screens\Select\EditSongSelect.cs" />
|
||||||
<Compile Include="Modes\UI\ComboCounter.cs" />
|
<Compile Include="Modes\UI\ComboCounter.cs" />
|
||||||
<Compile Include="Modes\UI\ComboResultCounter.cs" />
|
<Compile Include="Modes\UI\ComboResultCounter.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\RollingCounter.cs" />
|
<Compile Include="Graphics\UserInterface\RollingCounter.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user