mirror of
https://github.com/osukey/osukey.git
synced 2025-05-07 22:57:31 +09:00
Merge remote-tracking branch 'upstream/master' into login-updates
This commit is contained in:
commit
a6fd7f46c3
@ -1 +1 @@
|
|||||||
Subproject commit b10125a7334c07221503163a289522bddf6b793d
|
Subproject commit 16a01c7381e3ee8ef6b4fe863ba9232deba04c29
|
@ -13,6 +13,7 @@ using OpenTK.Graphics;
|
|||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Transformations;
|
using osu.Framework.Graphics.Transformations;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Desktop.VisualTests.Tests
|
namespace osu.Desktop.VisualTests.Tests
|
||||||
{
|
{
|
||||||
|
27
osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs
Normal file
27
osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.GameModes.Testing;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Screens.Menu;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Desktop.VisualTests.Tests
|
||||||
|
{
|
||||||
|
class TestCaseTwoLayerButton : TestCase
|
||||||
|
{
|
||||||
|
public override string Name => @"TwoLayerButton";
|
||||||
|
public override string Description => @"Back and skip and what not";
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
base.Reset();
|
||||||
|
|
||||||
|
Add(new BackButton());
|
||||||
|
Add(new SkipButton());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -183,6 +183,7 @@
|
|||||||
<Compile Include="Tests\TestCaseScoreCounter.cs" />
|
<Compile Include="Tests\TestCaseScoreCounter.cs" />
|
||||||
<Compile Include="Tests\TestCaseTextAwesome.cs" />
|
<Compile Include="Tests\TestCaseTextAwesome.cs" />
|
||||||
<Compile Include="Tests\TestCasePlaySongSelect.cs" />
|
<Compile Include="Tests\TestCasePlaySongSelect.cs" />
|
||||||
|
<Compile Include="Tests\TestCaseTwoLayerButton.cs" />
|
||||||
<Compile Include="VisualTestGame.cs" />
|
<Compile Include="VisualTestGame.cs" />
|
||||||
<Compile Include="Platform\TestStorage.cs" />
|
<Compile Include="Platform\TestStorage.cs" />
|
||||||
<Compile Include="Tests\TestCaseOptions.cs" />
|
<Compile Include="Tests\TestCaseOptions.cs" />
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using osu.Desktop.Beatmaps.IO;
|
using osu.Desktop.Beatmaps.IO;
|
||||||
using osu.Framework;
|
using osu.Framework;
|
||||||
using osu.Framework.Desktop;
|
using osu.Framework.Desktop;
|
||||||
@ -26,16 +27,22 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
LegacyFilesystemReader.Register();
|
LegacyFilesystemReader.Register();
|
||||||
|
|
||||||
|
// Back up the cwd before DesktopGameHost changes it
|
||||||
|
var cwd = Environment.CurrentDirectory;
|
||||||
|
|
||||||
using (DesktopGameHost host = Host.GetSuitableHost(@"osu", true))
|
using (DesktopGameHost host = Host.GetSuitableHost(@"osu", true))
|
||||||
{
|
{
|
||||||
if (!host.IsPrimaryInstance)
|
if (!host.IsPrimaryInstance)
|
||||||
{
|
{
|
||||||
var importer = new BeatmapImporter(host);
|
var importer = new BeatmapImporter(host);
|
||||||
|
// Restore the cwd so relative paths given at the command line work correctly
|
||||||
|
Directory.SetCurrentDirectory(cwd);
|
||||||
foreach (var file in args)
|
foreach (var file in args)
|
||||||
if (!importer.Import(file).Wait(1000))
|
{
|
||||||
|
Console.WriteLine(@"Importing {0}", file);
|
||||||
|
if (!importer.Import(Path.GetFullPath(file)).Wait(3000))
|
||||||
throw new TimeoutException(@"IPC took too long to send");
|
throw new TimeoutException(@"IPC took too long to send");
|
||||||
Console.WriteLine(@"Sent import requests to running instance");
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ using osu.Game.Modes.UI;
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
using osu.Framework.Graphics.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Game.Modes.Osu.UI
|
namespace osu.Game.Modes.Osu.UI
|
||||||
{
|
{
|
||||||
|
@ -31,31 +31,32 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
|
|
||||||
public List<BeatmapPanel> BeatmapPanels;
|
public List<BeatmapPanel> BeatmapPanels;
|
||||||
|
|
||||||
|
public BeatmapSetInfo BeatmapSet;
|
||||||
|
|
||||||
public BeatmapGroupState State
|
public BeatmapGroupState State
|
||||||
{
|
{
|
||||||
get { return state; }
|
get { return state; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
state = value;
|
switch (value)
|
||||||
switch (state)
|
|
||||||
{
|
{
|
||||||
case BeatmapGroupState.Expanded:
|
case BeatmapGroupState.Expanded:
|
||||||
foreach (BeatmapPanel panel in BeatmapPanels)
|
|
||||||
panel.FadeIn(250);
|
|
||||||
|
|
||||||
Header.State = PanelSelectedState.Selected;
|
Header.State = PanelSelectedState.Selected;
|
||||||
if (SelectedPanel != null)
|
foreach (BeatmapPanel panel in BeatmapPanels)
|
||||||
SelectedPanel.State = PanelSelectedState.Selected;
|
panel.State = panel == SelectedPanel ? PanelSelectedState.Selected : PanelSelectedState.NotSelected;
|
||||||
break;
|
break;
|
||||||
case BeatmapGroupState.Collapsed:
|
case BeatmapGroupState.Collapsed:
|
||||||
Header.State = PanelSelectedState.NotSelected;
|
Header.State = PanelSelectedState.NotSelected;
|
||||||
if (SelectedPanel != null)
|
|
||||||
SelectedPanel.State = PanelSelectedState.NotSelected;
|
|
||||||
|
|
||||||
foreach (BeatmapPanel panel in BeatmapPanels)
|
foreach (BeatmapPanel panel in BeatmapPanels)
|
||||||
panel.FadeOut(300, EasingTypes.OutQuint);
|
panel.State = PanelSelectedState.Hidden;
|
||||||
|
break;
|
||||||
|
case BeatmapGroupState.Hidden:
|
||||||
|
Header.State = PanelSelectedState.Hidden;
|
||||||
|
foreach (BeatmapPanel panel in BeatmapPanels)
|
||||||
|
panel.State = PanelSelectedState.Hidden;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
state = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +76,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
|
BeatmapSet = set;
|
||||||
Header.AddDifficultyIcons(BeatmapPanels);
|
Header.AddDifficultyIcons(BeatmapPanels);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,5 +113,6 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
{
|
{
|
||||||
Collapsed,
|
Collapsed,
|
||||||
Expanded,
|
Expanded,
|
||||||
|
Hidden,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,11 @@
|
|||||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
|
||||||
using osu.Framework.MathUtils;
|
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
@ -17,7 +14,6 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Modes;
|
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps.Drawables
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
{
|
{
|
||||||
@ -33,6 +29,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
protected override void Selected()
|
protected override void Selected()
|
||||||
{
|
{
|
||||||
base.Selected();
|
base.Selected();
|
||||||
|
|
||||||
GainedSelection?.Invoke(this);
|
GainedSelection?.Invoke(this);
|
||||||
|
|
||||||
background.ColourInfo = ColourInfo.GradientVertical(
|
background.ColourInfo = ColourInfo.GradientVertical(
|
||||||
|
@ -68,12 +68,6 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
FadeInFromZero(250);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Selected()
|
protected override void Selected()
|
||||||
{
|
{
|
||||||
base.Selected();
|
base.Selected();
|
||||||
|
@ -55,6 +55,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
{
|
{
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
|
case PanelSelectedState.Hidden:
|
||||||
case PanelSelectedState.NotSelected:
|
case PanelSelectedState.NotSelected:
|
||||||
Deselected();
|
Deselected();
|
||||||
break;
|
break;
|
||||||
@ -62,6 +63,11 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
Selected();
|
Selected();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state == PanelSelectedState.Hidden)
|
||||||
|
FadeOut(300, EasingTypes.OutQuint);
|
||||||
|
else
|
||||||
|
FadeIn(250);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PanelSelectedState state = PanelSelectedState.NotSelected;
|
private PanelSelectedState state = PanelSelectedState.NotSelected;
|
||||||
@ -112,6 +118,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
|
|
||||||
enum PanelSelectedState
|
enum PanelSelectedState
|
||||||
{
|
{
|
||||||
|
Hidden,
|
||||||
NotSelected,
|
NotSelected,
|
||||||
Selected
|
Selected
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
@ -10,6 +11,8 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Graphics.Transformations;
|
using osu.Framework.Graphics.Transformations;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.Cursor
|
namespace osu.Game.Graphics.Cursor
|
||||||
{
|
{
|
||||||
@ -38,6 +41,8 @@ namespace osu.Game.Graphics.Cursor
|
|||||||
|
|
||||||
class OsuCursor : Container
|
class OsuCursor : Container
|
||||||
{
|
{
|
||||||
|
private BindableDouble cursorScale;
|
||||||
|
private Sprite sprite;
|
||||||
public OsuCursor()
|
public OsuCursor()
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
@ -45,15 +50,24 @@ namespace osu.Game.Graphics.Cursor
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(TextureStore textures)
|
private void load(TextureStore textures, OsuConfigManager config)
|
||||||
{
|
{
|
||||||
|
cursorScale = (BindableDouble)config.GetBindable<double>(OsuConfig.CursorSize);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Sprite
|
sprite = new Sprite
|
||||||
{
|
{
|
||||||
|
Scale = new Vector2((float)cursorScale),
|
||||||
Texture = textures.Get(@"Cursor/cursor")
|
Texture = textures.Get(@"Cursor/cursor")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
cursorScale.ValueChanged += scaleChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scaleChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
sprite.Scale = new Vector2((float)cursorScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,163 +3,26 @@
|
|||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
|
||||||
using OpenTK;
|
|
||||||
using OpenTK.Graphics;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Transformations;
|
|
||||||
using osu.Framework.Input;
|
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
// Basic back button as it was on stable (kinda). No skinning possible for now
|
public class BackButton : TwoLayerButton
|
||||||
public class BackButton : ClickableContainer
|
|
||||||
{
|
{
|
||||||
private TextAwesome icon;
|
|
||||||
|
|
||||||
private Box leftBox;
|
|
||||||
private Box rightBox;
|
|
||||||
|
|
||||||
private const double transform_time = 600;
|
|
||||||
private const int pulse_length = 250;
|
|
||||||
|
|
||||||
private const float shear = 0.15f;
|
|
||||||
|
|
||||||
public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50);
|
|
||||||
public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50);
|
|
||||||
private AudioSample sampleClick;
|
|
||||||
|
|
||||||
public BackButton()
|
public BackButton()
|
||||||
{
|
{
|
||||||
Size = SIZE_RETRACTED;
|
Text = @"Back";
|
||||||
}
|
Icon = FontAwesome.fa_osu_left_o;
|
||||||
|
Anchor = Anchor.BottomLeft;
|
||||||
public override bool Contains(Vector2 screenSpacePos) => leftBox.Contains(screenSpacePos) || rightBox.Contains(screenSpacePos);
|
Origin = Anchor.BottomLeft;
|
||||||
|
|
||||||
protected override bool OnHover(InputState state)
|
|
||||||
{
|
|
||||||
icon.ClearTransformations();
|
|
||||||
|
|
||||||
ResizeTo(SIZE_EXTENDED, transform_time, EasingTypes.OutElastic);
|
|
||||||
|
|
||||||
int duration = 0; //(int)(Game.Audio.BeatLength / 2);
|
|
||||||
if (duration == 0) duration = pulse_length;
|
|
||||||
|
|
||||||
double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration;
|
|
||||||
double startTime = Time.Current + offset;
|
|
||||||
|
|
||||||
// basic pulse
|
|
||||||
icon.Transforms.Add(new TransformScale
|
|
||||||
{
|
|
||||||
StartValue = new Vector2(1.1f),
|
|
||||||
EndValue = Vector2.One,
|
|
||||||
StartTime = startTime,
|
|
||||||
EndTime = startTime + duration,
|
|
||||||
Easing = EasingTypes.Out,
|
|
||||||
LoopCount = -1,
|
|
||||||
LoopDelay = duration
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnHoverLost(InputState state)
|
|
||||||
{
|
|
||||||
icon.ClearTransformations();
|
|
||||||
|
|
||||||
ResizeTo(SIZE_RETRACTED, transform_time, EasingTypes.OutElastic);
|
|
||||||
|
|
||||||
int duration = 0; //(int)(Game.Audio.BeatLength);
|
|
||||||
if (duration == 0) duration = pulse_length * 2;
|
|
||||||
|
|
||||||
double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration;
|
|
||||||
double startTime = Time.Current + offset;
|
|
||||||
|
|
||||||
// slow pulse
|
|
||||||
icon.Transforms.Add(new TransformScale
|
|
||||||
{
|
|
||||||
StartValue = new Vector2(1.1f),
|
|
||||||
EndValue = Vector2.One,
|
|
||||||
StartTime = startTime,
|
|
||||||
EndTime = startTime + duration,
|
|
||||||
Easing = EasingTypes.Out,
|
|
||||||
LoopCount = -1,
|
|
||||||
LoopDelay = duration
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio, OsuColour colours)
|
private void load(AudioManager audio, OsuColour colours)
|
||||||
{
|
{
|
||||||
sampleClick = audio.Sample.Get(@"Menu/menuback");
|
ActivationSound = audio.Sample.Get(@"Menu/menuback");
|
||||||
Children = new Drawable[]
|
Colour = colours.Pink;
|
||||||
{
|
HoverColour = colours.PinkDark;
|
||||||
new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Width = 0.4f,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
leftBox = new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Colour = colours.PinkDark,
|
|
||||||
Shear = new Vector2(shear, 0),
|
|
||||||
},
|
|
||||||
icon = new TextAwesome
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
TextSize = 25,
|
|
||||||
Icon = FontAwesome.fa_osu_left_o
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
Origin = Anchor.TopRight,
|
|
||||||
Anchor = Anchor.TopRight,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Width = 0.6f,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
rightBox = new Box
|
|
||||||
{
|
|
||||||
Colour = colours.Pink,
|
|
||||||
Origin = Anchor.TopLeft,
|
|
||||||
Anchor = Anchor.TopLeft,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Shear = new Vector2(shear, 0),
|
|
||||||
EdgeSmoothness = new Vector2(1.5f, 0),
|
|
||||||
},
|
|
||||||
new SpriteText
|
|
||||||
{
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Text = @"Back",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnClick(InputState state)
|
|
||||||
{
|
|
||||||
var flash = new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Shear = new Vector2(shear, 0),
|
|
||||||
Colour = Color4.White.Opacity(0.5f),
|
|
||||||
};
|
|
||||||
Add(flash);
|
|
||||||
|
|
||||||
flash.FadeOutFromOne(200);
|
|
||||||
flash.Expire();
|
|
||||||
|
|
||||||
sampleClick.Play();
|
|
||||||
|
|
||||||
return base.OnClick(state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
237
osu.Game/Graphics/UserInterface/TwoLayerButton.cs
Normal file
237
osu.Game/Graphics/UserInterface/TwoLayerButton.cs
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Primitives;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Transformations;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.UserInterface
|
||||||
|
{
|
||||||
|
public class TwoLayerButton : ClickableContainer
|
||||||
|
{
|
||||||
|
private TextAwesome icon;
|
||||||
|
|
||||||
|
public Box IconLayer;
|
||||||
|
public Box TextLayer;
|
||||||
|
|
||||||
|
private const int transform_time = 600;
|
||||||
|
private const int pulse_length = 250;
|
||||||
|
|
||||||
|
private const float shear = 0.1f;
|
||||||
|
|
||||||
|
public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50);
|
||||||
|
public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50);
|
||||||
|
public AudioSample ActivationSound;
|
||||||
|
private SpriteText text;
|
||||||
|
|
||||||
|
public Color4 HoverColour;
|
||||||
|
private Container c1;
|
||||||
|
private Container c2;
|
||||||
|
|
||||||
|
public Color4 Colour
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
TextLayer.Colour = value;
|
||||||
|
IconLayer.Colour = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Anchor Origin
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return base.Origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.Origin = value;
|
||||||
|
c1.Origin = c1.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopLeft : Anchor.TopRight;
|
||||||
|
c2.Origin = c2.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopRight : Anchor.TopLeft;
|
||||||
|
|
||||||
|
Margin = new MarginPadding
|
||||||
|
{
|
||||||
|
Right = (value & Anchor.x2) > 0 ? -SIZE_RETRACTED.X * shear * 0.5f : 0
|
||||||
|
};
|
||||||
|
|
||||||
|
c1.Depth = (value & Anchor.x2) > 0 ? 0 : 1;
|
||||||
|
c2.Depth = (value & Anchor.x2) > 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TwoLayerButton()
|
||||||
|
{
|
||||||
|
Size = SIZE_RETRACTED;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
c2 = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Width = 0.4f,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container {
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Shear = new Vector2(shear, 0),
|
||||||
|
Masking = true,
|
||||||
|
EdgeEffect = new EdgeEffect {
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = Color4.Black.Opacity(0.2f),
|
||||||
|
Offset = new Vector2(2, 0),
|
||||||
|
Radius = 2,
|
||||||
|
},
|
||||||
|
Children = new [] {
|
||||||
|
IconLayer = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
EdgeSmoothness = new Vector2(1.5f, 0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon = new TextAwesome
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
TextSize = 25,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
c1 = new Container
|
||||||
|
{
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Width = 0.6f,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container {
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Shear = new Vector2(shear, 0),
|
||||||
|
Masking = true,
|
||||||
|
EdgeEffect = new EdgeEffect {
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = Color4.Black.Opacity(0.2f),
|
||||||
|
Offset = new Vector2(2, 0),
|
||||||
|
Radius = 2,
|
||||||
|
},
|
||||||
|
Children = new [] {
|
||||||
|
TextLayer = new Box
|
||||||
|
{
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
EdgeSmoothness = new Vector2(1.5f, 0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text = new SpriteText
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontAwesome Icon
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
icon.Icon = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
text.Text = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Contains(Vector2 screenSpacePos) => IconLayer.Contains(screenSpacePos) || TextLayer.Contains(screenSpacePos);
|
||||||
|
|
||||||
|
protected override bool OnHover(InputState state)
|
||||||
|
{
|
||||||
|
icon.ClearTransformations();
|
||||||
|
|
||||||
|
ResizeTo(SIZE_EXTENDED, transform_time, EasingTypes.OutElastic);
|
||||||
|
|
||||||
|
int duration = 0; //(int)(Game.Audio.BeatLength / 2);
|
||||||
|
if (duration == 0) duration = pulse_length;
|
||||||
|
|
||||||
|
IconLayer.FadeColour(HoverColour, transform_time, EasingTypes.OutElastic);
|
||||||
|
|
||||||
|
double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration;
|
||||||
|
double startTime = Time.Current + offset;
|
||||||
|
|
||||||
|
// basic pulse
|
||||||
|
icon.Transforms.Add(new TransformScale
|
||||||
|
{
|
||||||
|
StartValue = new Vector2(1.1f),
|
||||||
|
EndValue = Vector2.One,
|
||||||
|
StartTime = startTime,
|
||||||
|
EndTime = startTime + duration,
|
||||||
|
Easing = EasingTypes.Out,
|
||||||
|
LoopCount = -1,
|
||||||
|
LoopDelay = duration
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(InputState state)
|
||||||
|
{
|
||||||
|
icon.ClearTransformations();
|
||||||
|
|
||||||
|
ResizeTo(SIZE_RETRACTED, transform_time, EasingTypes.OutElastic);
|
||||||
|
|
||||||
|
IconLayer.FadeColour(TextLayer.Colour, transform_time, EasingTypes.OutElastic);
|
||||||
|
|
||||||
|
int duration = 0; //(int)(Game.Audio.BeatLength);
|
||||||
|
if (duration == 0) duration = pulse_length * 2;
|
||||||
|
|
||||||
|
double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration;
|
||||||
|
double startTime = Time.Current + offset;
|
||||||
|
|
||||||
|
// slow pulse
|
||||||
|
icon.Transforms.Add(new TransformScale
|
||||||
|
{
|
||||||
|
StartValue = new Vector2(1.1f),
|
||||||
|
EndValue = Vector2.One,
|
||||||
|
StartTime = startTime,
|
||||||
|
EndTime = startTime + duration,
|
||||||
|
Easing = EasingTypes.Out,
|
||||||
|
LoopCount = -1,
|
||||||
|
LoopDelay = duration
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnClick(InputState state)
|
||||||
|
{
|
||||||
|
var flash = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Shear = new Vector2(shear, 0),
|
||||||
|
Colour = Color4.White.Opacity(0.5f),
|
||||||
|
};
|
||||||
|
Add(flash);
|
||||||
|
|
||||||
|
flash.Alpha = 1;
|
||||||
|
flash.FadeOut(500, EasingTypes.OutQuint);
|
||||||
|
flash.Expire();
|
||||||
|
|
||||||
|
ActivationSound.Play();
|
||||||
|
|
||||||
|
return base.OnClick(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using osu.Game.Modes.Objects;
|
using osu.Game.Modes.Objects;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.Graphics.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Game.Modes.UI
|
namespace osu.Game.Modes.UI
|
||||||
{
|
{
|
||||||
|
@ -22,17 +22,19 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
{
|
{
|
||||||
return beatmap;
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (beatmap == value)
|
if (beatmap == value && beatmap != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
beatmap = value;
|
beatmap = value;
|
||||||
|
|
||||||
Schedule(() =>
|
Schedule(() =>
|
||||||
{
|
{
|
||||||
Background newBackground = new BeatmapBackground(beatmap);
|
Background newBackground;
|
||||||
|
if (beatmap == null)
|
||||||
|
newBackground = new Background(@"Backgrounds/bg1");
|
||||||
|
else
|
||||||
|
newBackground = new BeatmapBackground(beatmap);
|
||||||
|
|
||||||
newBackground.Preload(Game, delegate
|
newBackground.Preload(Game, delegate
|
||||||
{
|
{
|
||||||
@ -84,7 +86,6 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
{
|
{
|
||||||
Sprite.Texture = beatmap.Background;
|
Sprite.Texture = beatmap.Background;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
Action = onOsuLogo,
|
Action = onOsuLogo,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre
|
Anchor = Anchor.Centre,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using OpenTK;
|
|
||||||
using OpenTK.Graphics;
|
|
||||||
using osu.Framework;
|
|
||||||
using osu.Framework.Allocation;
|
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.Framework.Graphics.Textures;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
public abstract class KeyCounter : Container
|
public abstract class KeyCounter : Container
|
||||||
{
|
{
|
@ -2,11 +2,11 @@
|
|||||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
public class KeyCounterCollection : FlowContainer<KeyCounter>
|
public class KeyCounterCollection : FlowContainer<KeyCounter>
|
||||||
{
|
{
|
@ -1,11 +1,11 @@
|
|||||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using OpenTK.Input;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
public class KeyCounterKeyboard : KeyCounter
|
public class KeyCounterKeyboard : KeyCounter
|
||||||
{
|
{
|
@ -1,12 +1,12 @@
|
|||||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using OpenTK;
|
|
||||||
using OpenTK.Input;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
public class KeyCounterMouse : KeyCounter
|
public class KeyCounterMouse : KeyCounter
|
||||||
{
|
{
|
@ -1,22 +1,16 @@
|
|||||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
|
||||||
using osu.Framework.Platform;
|
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Modes;
|
using osu.Game.Modes;
|
||||||
using osu.Game.Modes.Objects;
|
|
||||||
using osu.Game.Modes.Objects.Drawables;
|
using osu.Game.Modes.Objects.Drawables;
|
||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
using OpenTK.Input;
|
|
||||||
using MouseState = osu.Framework.Input.MouseState;
|
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.GameModes;
|
using osu.Framework.GameModes;
|
||||||
using osu.Game.Modes.UI;
|
using osu.Game.Modes.UI;
|
||||||
@ -25,6 +19,8 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Overlays.Pause;
|
using osu.Game.Overlays.Pause;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
@ -65,6 +61,7 @@ namespace osu.Game.Screens.Play
|
|||||||
private ScoreProcessor scoreProcessor;
|
private ScoreProcessor scoreProcessor;
|
||||||
private HitRenderer hitRenderer;
|
private HitRenderer hitRenderer;
|
||||||
private Bindable<int> dimLevel;
|
private Bindable<int> dimLevel;
|
||||||
|
private SkipButton skipButton;
|
||||||
|
|
||||||
private ScoreOverlay scoreOverlay;
|
private ScoreOverlay scoreOverlay;
|
||||||
private PauseOverlay pauseOverlay;
|
private PauseOverlay pauseOverlay;
|
||||||
@ -149,6 +146,7 @@ namespace osu.Game.Screens.Play
|
|||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
hitRenderer,
|
hitRenderer,
|
||||||
|
skipButton = new SkipButton { Alpha = 0 },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scoreOverlay,
|
scoreOverlay,
|
||||||
@ -156,6 +154,33 @@ namespace osu.Game.Screens.Play
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initializeSkipButton()
|
||||||
|
{
|
||||||
|
const double skip_required_cutoff = 3000;
|
||||||
|
const double fade_time = 300;
|
||||||
|
|
||||||
|
double firstHitObject = Beatmap.Beatmap.HitObjects.First().StartTime;
|
||||||
|
|
||||||
|
if (firstHitObject < skip_required_cutoff)
|
||||||
|
{
|
||||||
|
skipButton.Alpha = 0;
|
||||||
|
skipButton.Expire();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
skipButton.FadeInFromZero(fade_time);
|
||||||
|
|
||||||
|
skipButton.Action = () =>
|
||||||
|
{
|
||||||
|
sourceClock.Seek(firstHitObject - skip_required_cutoff - fade_time);
|
||||||
|
skipButton.Action = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
skipButton.Delay(firstHitObject - skip_required_cutoff - fade_time);
|
||||||
|
skipButton.FadeOut(fade_time);
|
||||||
|
skipButton.Expire();
|
||||||
|
}
|
||||||
|
|
||||||
public void Pause(bool force = false)
|
public void Pause(bool force = false)
|
||||||
{
|
{
|
||||||
if (canPause || force)
|
if (canPause || force)
|
||||||
@ -220,6 +245,7 @@ namespace osu.Game.Screens.Play
|
|||||||
Schedule(() =>
|
Schedule(() =>
|
||||||
{
|
{
|
||||||
sourceClock.Start();
|
sourceClock.Start();
|
||||||
|
initializeSkipButton();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
osu.Game/Screens/Play/SkipButton.cs
Normal file
32
osu.Game/Screens/Play/SkipButton.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//Copyright (c) 2007-2016 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.Audio;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play
|
||||||
|
{
|
||||||
|
public class SkipButton : TwoLayerButton
|
||||||
|
{
|
||||||
|
private readonly double skipDestination;
|
||||||
|
|
||||||
|
public SkipButton()
|
||||||
|
{
|
||||||
|
Text = @"Skip";
|
||||||
|
Icon = FontAwesome.fa_osu_right_o;
|
||||||
|
Anchor = Anchor.BottomRight;
|
||||||
|
Origin = Anchor.BottomRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(AudioManager audio, OsuColour colours)
|
||||||
|
{
|
||||||
|
ActivationSound = audio.Sample.Get(@"Menu/menuhit");
|
||||||
|
Colour = colours.Yellow;
|
||||||
|
HoverColour = colours.YellowDark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,11 +16,12 @@ using osu.Game.Beatmaps.Drawables;
|
|||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
using System.Collections;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
namespace osu.Game.Screens.Select
|
||||||
{
|
{
|
||||||
class CarouselContainer : ScrollContainer
|
class CarouselContainer : ScrollContainer, IEnumerable<BeatmapGroup>
|
||||||
{
|
{
|
||||||
private Container<Panel> scrollableContent;
|
private Container<Panel> scrollableContent;
|
||||||
private List<BeatmapGroup> groups = new List<BeatmapGroup>();
|
private List<BeatmapGroup> groups = new List<BeatmapGroup>();
|
||||||
@ -96,10 +97,10 @@ namespace osu.Game.Screens.Select
|
|||||||
computeYPositions();
|
computeYPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void movePanel(Panel panel, bool advance, ref float currentY)
|
private void movePanel(Panel panel, bool advance, bool animated, ref float currentY)
|
||||||
{
|
{
|
||||||
yPositions.Add(currentY);
|
yPositions.Add(currentY);
|
||||||
panel.MoveToY(currentY, 750, EasingTypes.OutExpo);
|
panel.MoveToY(currentY, animated && (panel.IsOnScreen || panel.State != PanelSelectedState.Hidden) ? 750 : 0, EasingTypes.OutExpo);
|
||||||
|
|
||||||
if (advance)
|
if (advance)
|
||||||
currentY += panel.DrawHeight + 5;
|
currentY += panel.DrawHeight + 5;
|
||||||
@ -109,7 +110,7 @@ namespace osu.Game.Screens.Select
|
|||||||
/// Computes the target Y positions for every panel in the carousel.
|
/// Computes the target Y positions for every panel in the carousel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The Y position of the currently selected panel.</returns>
|
/// <returns>The Y position of the currently selected panel.</returns>
|
||||||
private float computeYPositions()
|
private float computeYPositions(bool animated = true)
|
||||||
{
|
{
|
||||||
yPositions.Clear();
|
yPositions.Clear();
|
||||||
|
|
||||||
@ -118,7 +119,7 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
foreach (BeatmapGroup group in groups)
|
foreach (BeatmapGroup group in groups)
|
||||||
{
|
{
|
||||||
movePanel(group.Header, true, ref currentY);
|
movePanel(group.Header, group.State != BeatmapGroupState.Hidden, animated, ref currentY);
|
||||||
|
|
||||||
if (group.State == BeatmapGroupState.Expanded)
|
if (group.State == BeatmapGroupState.Expanded)
|
||||||
{
|
{
|
||||||
@ -136,7 +137,7 @@ namespace osu.Game.Screens.Select
|
|||||||
if (panel.Alpha == 0)
|
if (panel.Alpha == 0)
|
||||||
panel.MoveToY(headerY);
|
panel.MoveToY(headerY);
|
||||||
|
|
||||||
movePanel(panel, true, ref currentY);
|
movePanel(panel, true, animated, ref currentY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -146,7 +147,7 @@ namespace osu.Game.Screens.Select
|
|||||||
foreach (BeatmapPanel panel in group.BeatmapPanels)
|
foreach (BeatmapPanel panel in group.BeatmapPanels)
|
||||||
{
|
{
|
||||||
panel.MoveToX(0, 500, EasingTypes.OutExpo);
|
panel.MoveToX(0, 500, EasingTypes.OutExpo);
|
||||||
movePanel(panel, false, ref currentY);
|
movePanel(panel, false, animated, ref currentY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,30 +158,30 @@ namespace osu.Game.Screens.Select
|
|||||||
return selectedY;
|
return selectedY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectBeatmap(BeatmapInfo beatmap)
|
public void SelectBeatmap(BeatmapInfo beatmap, bool animated = true)
|
||||||
{
|
{
|
||||||
foreach (BeatmapGroup group in groups)
|
foreach (BeatmapGroup group in groups)
|
||||||
{
|
{
|
||||||
var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(beatmap));
|
var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(beatmap));
|
||||||
if (panel != null)
|
if (panel != null)
|
||||||
{
|
{
|
||||||
SelectGroup(group, panel);
|
SelectGroup(group, panel, animated);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectGroup(BeatmapGroup group, BeatmapPanel panel)
|
public void SelectGroup(BeatmapGroup group, BeatmapPanel panel, bool animated = true)
|
||||||
{
|
{
|
||||||
if (SelectedGroup != null && SelectedGroup != group)
|
if (SelectedGroup != null && SelectedGroup != group && SelectedGroup.State != BeatmapGroupState.Hidden)
|
||||||
SelectedGroup.State = BeatmapGroupState.Collapsed;
|
SelectedGroup.State = BeatmapGroupState.Collapsed;
|
||||||
|
|
||||||
SelectedGroup = group;
|
SelectedGroup = group;
|
||||||
panel.State = PanelSelectedState.Selected;
|
panel.State = PanelSelectedState.Selected;
|
||||||
SelectedPanel = panel;
|
SelectedPanel = panel;
|
||||||
|
|
||||||
float selectedY = computeYPositions();
|
float selectedY = computeYPositions(animated);
|
||||||
ScrollTo(selectedY);
|
ScrollTo(selectedY, animated);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float offsetX(float dist, float halfHeight)
|
private static float offsetX(float dist, float halfHeight)
|
||||||
@ -201,7 +202,9 @@ namespace osu.Game.Screens.Select
|
|||||||
/// <param name="halfHeight">Half the draw height of the carousel container.</param>
|
/// <param name="halfHeight">Half the draw height of the carousel container.</param>
|
||||||
private void updatePanel(Panel p, float halfHeight)
|
private void updatePanel(Panel p, float halfHeight)
|
||||||
{
|
{
|
||||||
float panelDrawY = p.Position.Y - Current + p.DrawHeight / 2;
|
var height = p.IsVisible ? p.DrawHeight : 0;
|
||||||
|
|
||||||
|
float panelDrawY = p.Position.Y - Current + height / 2;
|
||||||
float dist = Math.Abs(1f - panelDrawY / halfHeight);
|
float dist = Math.Abs(1f - panelDrawY / halfHeight);
|
||||||
|
|
||||||
// Setting the origin position serves as an additive position on top of potential
|
// Setting the origin position serves as an additive position on top of potential
|
||||||
@ -243,7 +246,8 @@ namespace osu.Game.Screens.Select
|
|||||||
for (int i = firstIndex; i < lastIndex; ++i)
|
for (int i = firstIndex; i < lastIndex; ++i)
|
||||||
{
|
{
|
||||||
Panel p = Lifetime[i];
|
Panel p = Lifetime[i];
|
||||||
p.IsOnScreen = true;
|
if (p.State != PanelSelectedState.Hidden)
|
||||||
|
p.IsOnScreen = true; //we don't want to update the on-screen state of hidden pannels as they have incorrect (stacked) y values.
|
||||||
updatePanel(p, halfHeight);
|
updatePanel(p, halfHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -271,23 +275,35 @@ namespace osu.Game.Screens.Select
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direction != 0)
|
if (direction == 0)
|
||||||
|
return base.OnKeyDown(state, args);
|
||||||
|
|
||||||
|
if (!skipDifficulties)
|
||||||
{
|
{
|
||||||
int index = SelectedGroup.BeatmapPanels.IndexOf(SelectedPanel) + direction;
|
int i = SelectedGroup.BeatmapPanels.IndexOf(SelectedPanel) + direction;
|
||||||
|
|
||||||
if (!skipDifficulties && index >= 0 && index < SelectedGroup.BeatmapPanels.Count)
|
if (i >= 0 && i < SelectedGroup.BeatmapPanels.Count)
|
||||||
//changing difficulty panel, not set.
|
|
||||||
SelectGroup(SelectedGroup, SelectedGroup.BeatmapPanels[index]);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
index = (groups.IndexOf(SelectedGroup) + direction + groups.Count) % groups.Count;
|
//changing difficulty panel, not set.
|
||||||
SelectBeatmap(groups[index].BeatmapPanels.First().Beatmap);
|
SelectGroup(SelectedGroup, SelectedGroup.BeatmapPanels[i]);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.OnKeyDown(state, args);
|
int startIndex = groups.IndexOf(SelectedGroup);
|
||||||
|
int index = startIndex;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
index = (index + direction + groups.Count) % groups.Count;
|
||||||
|
if (groups[index].State != BeatmapGroupState.Hidden)
|
||||||
|
{
|
||||||
|
SelectBeatmap(groups[index].BeatmapPanels.First().Beatmap);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} while (index != startIndex);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectRandom()
|
public void SelectRandom()
|
||||||
@ -300,5 +316,9 @@ namespace osu.Game.Screens.Select
|
|||||||
return;
|
return;
|
||||||
SelectGroup(group, panel);
|
SelectGroup(group, panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerator<BeatmapGroup> GetEnumerator() => groups.GetEnumerator();
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
279
osu.Game/Screens/Select/FilterControl.cs
Normal file
279
osu.Game/Screens/Select/FilterControl.cs
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
using System;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
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.Framework.Input;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select
|
||||||
|
{
|
||||||
|
public class FilterControl : Container
|
||||||
|
{
|
||||||
|
public Action FilterChanged;
|
||||||
|
|
||||||
|
public string Search => searchTextBox.Text;
|
||||||
|
public SortMode Sort { get; private set; } = SortMode.Title;
|
||||||
|
public Action Exit;
|
||||||
|
|
||||||
|
private SearchTextBox searchTextBox;
|
||||||
|
|
||||||
|
public FilterControl()
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Black,
|
||||||
|
Alpha = 0.6f,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new FlowContainer
|
||||||
|
{
|
||||||
|
Padding = new MarginPadding(20),
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Width = 0.4f, // TODO: InnerWidth property or something
|
||||||
|
Direction = FlowDirection.VerticalOnly,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
searchTextBox = new SearchTextBox { RelativeSizeAxes = Axes.X },
|
||||||
|
new GroupSortTabs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
searchTextBox.OnChange += (TextBox sender, bool newText) =>
|
||||||
|
{
|
||||||
|
if (newText)
|
||||||
|
FilterChanged?.Invoke();
|
||||||
|
};
|
||||||
|
searchTextBox.Exit = () => Exit?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Deactivate()
|
||||||
|
{
|
||||||
|
searchTextBox.GrabFocus = false;
|
||||||
|
searchTextBox.TriggerFocusLost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activate()
|
||||||
|
{
|
||||||
|
searchTextBox.GrabFocus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TabItem : ClickableContainer
|
||||||
|
{
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get { return text.Text; }
|
||||||
|
set { text.Text = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FadeActive()
|
||||||
|
{
|
||||||
|
box.FadeIn(300);
|
||||||
|
text.FadeColour(Color4.White, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FadeInactive()
|
||||||
|
{
|
||||||
|
box.FadeOut(300);
|
||||||
|
text.FadeColour(fadeColour, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool active;
|
||||||
|
public bool Active
|
||||||
|
{
|
||||||
|
get { return active; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
active = value;
|
||||||
|
if (active)
|
||||||
|
FadeActive();
|
||||||
|
else
|
||||||
|
FadeInactive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SpriteText text;
|
||||||
|
private Box box;
|
||||||
|
private Color4 fadeColour;
|
||||||
|
|
||||||
|
protected override bool OnHover(InputState state)
|
||||||
|
{
|
||||||
|
if (!active)
|
||||||
|
FadeActive();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(InputState state)
|
||||||
|
{
|
||||||
|
if (!active)
|
||||||
|
FadeInactive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TabItem()
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
text = new SpriteText
|
||||||
|
{
|
||||||
|
Margin = new MarginPadding(5),
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-Bold",
|
||||||
|
},
|
||||||
|
box = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 1,
|
||||||
|
Alpha = 0,
|
||||||
|
Colour = Color4.White,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
text.Colour = colours.Blue;
|
||||||
|
fadeColour = colours.Blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GroupSortTabs : Container
|
||||||
|
{
|
||||||
|
private TextAwesome groupsEllipsis, sortEllipsis;
|
||||||
|
private SpriteText sortLabel;
|
||||||
|
|
||||||
|
public GroupSortTabs()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 1,
|
||||||
|
Colour = OsuColour.Gray(80),
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
},
|
||||||
|
new FlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FlowDirection.HorizontalOnly,
|
||||||
|
Spacing = new Vector2(10, 0),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new TabItem
|
||||||
|
{
|
||||||
|
Text = "All",
|
||||||
|
Active = true,
|
||||||
|
},
|
||||||
|
new TabItem
|
||||||
|
{
|
||||||
|
Text = "Recently Played",
|
||||||
|
Active = false,
|
||||||
|
},
|
||||||
|
new TabItem
|
||||||
|
{
|
||||||
|
Text = "Collections",
|
||||||
|
Active = false,
|
||||||
|
},
|
||||||
|
groupsEllipsis = new TextAwesome
|
||||||
|
{
|
||||||
|
Icon = FontAwesome.fa_ellipsis_h,
|
||||||
|
TextSize = 14,
|
||||||
|
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new FlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FlowDirection.HorizontalOnly,
|
||||||
|
Spacing = new Vector2(10, 0),
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
sortLabel = new SpriteText
|
||||||
|
{
|
||||||
|
Font = @"Exo2.0-Bold",
|
||||||
|
Text = "Sort results by",
|
||||||
|
TextSize = 14,
|
||||||
|
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
||||||
|
},
|
||||||
|
new TabItem
|
||||||
|
{
|
||||||
|
Text = "Artist",
|
||||||
|
Active = true,
|
||||||
|
},
|
||||||
|
sortEllipsis = new TextAwesome
|
||||||
|
{
|
||||||
|
Icon = FontAwesome.fa_ellipsis_h,
|
||||||
|
TextSize = 14,
|
||||||
|
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
groupsEllipsis.Colour = colours.Blue;
|
||||||
|
sortLabel.Colour = colours.GreenLight;
|
||||||
|
sortEllipsis.Colour = colours.GreenLight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SortMode
|
||||||
|
{
|
||||||
|
Arist,
|
||||||
|
BPM,
|
||||||
|
Creator,
|
||||||
|
DateAdded,
|
||||||
|
Difficulty,
|
||||||
|
Length,
|
||||||
|
RankAchieved,
|
||||||
|
Title
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GroupMode
|
||||||
|
{
|
||||||
|
NoGrouping,
|
||||||
|
Arist,
|
||||||
|
BPM,
|
||||||
|
Creator,
|
||||||
|
DateAdded,
|
||||||
|
Difficulty,
|
||||||
|
Length,
|
||||||
|
RankAchieved,
|
||||||
|
Title,
|
||||||
|
Collections,
|
||||||
|
Favorites,
|
||||||
|
MyMaps,
|
||||||
|
RankedStatus,
|
||||||
|
RecentlyPlayed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,9 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Threading;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
namespace osu.Game.Screens.Select
|
||||||
{
|
{
|
||||||
@ -51,6 +54,8 @@ namespace osu.Game.Screens.Select
|
|||||||
private AudioSample sampleChangeDifficulty;
|
private AudioSample sampleChangeDifficulty;
|
||||||
private AudioSample sampleChangeBeatmap;
|
private AudioSample sampleChangeBeatmap;
|
||||||
|
|
||||||
|
private List<BeatmapGroup> beatmapGroups;
|
||||||
|
|
||||||
private Footer footer;
|
private Footer footer;
|
||||||
|
|
||||||
class WedgeBackground : Container
|
class WedgeBackground : Container
|
||||||
@ -82,10 +87,11 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
|
|
||||||
Player player;
|
Player player;
|
||||||
|
FilterControl filter;
|
||||||
|
|
||||||
private void start()
|
private void start()
|
||||||
{
|
{
|
||||||
if (player != null)
|
if (player != null || Beatmap == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//in the future we may want to move this logic to a PlayerLoader gamemode or similar, so we can rely on the SongSelect transition
|
//in the future we may want to move this logic to a PlayerLoader gamemode or similar, so we can rely on the SongSelect transition
|
||||||
@ -111,7 +117,8 @@ namespace osu.Game.Screens.Select
|
|||||||
OsuGame osuGame, OsuColour colours)
|
OsuGame osuGame, OsuColour colours)
|
||||||
{
|
{
|
||||||
const float carouselWidth = 640;
|
const float carouselWidth = 640;
|
||||||
|
const float bottomToolHeight = 50;
|
||||||
|
beatmapGroups = new List<BeatmapGroup>();
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new ParallaxContainer
|
new ParallaxContainer
|
||||||
@ -134,6 +141,13 @@ namespace osu.Game.Screens.Select
|
|||||||
Anchor = Anchor.CentreRight,
|
Anchor = Anchor.CentreRight,
|
||||||
Origin = Anchor.CentreRight,
|
Origin = Anchor.CentreRight,
|
||||||
},
|
},
|
||||||
|
filter = new FilterControl
|
||||||
|
{
|
||||||
|
Position = wedged_container_start_position,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
FilterChanged = filterChanged,
|
||||||
|
Exit = Exit,
|
||||||
|
},
|
||||||
beatmapInfoWedge = new BeatmapInfoWedge
|
beatmapInfoWedge = new BeatmapInfoWedge
|
||||||
{
|
{
|
||||||
Alpha = 0,
|
Alpha = 0,
|
||||||
@ -174,9 +188,43 @@ namespace osu.Game.Screens.Select
|
|||||||
Task.Factory.StartNew(() => addBeatmapSets(game, initialAddSetsTask.Token), initialAddSetsTask.Token);
|
Task.Factory.StartNew(() => addBeatmapSets(game, initialAddSetsTask.Token), initialAddSetsTask.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ScheduledDelegate filterTask;
|
||||||
|
|
||||||
|
private void filterChanged()
|
||||||
|
{
|
||||||
|
filterTask?.Cancel();
|
||||||
|
filterTask = Scheduler.AddDelayed(() =>
|
||||||
|
{
|
||||||
|
filterTask = null;
|
||||||
|
var search = filter.Search;
|
||||||
|
BeatmapGroup newSelection = null;
|
||||||
|
foreach (var beatmapGroup in carousel)
|
||||||
|
{
|
||||||
|
var set = beatmapGroup.BeatmapSet;
|
||||||
|
bool match = string.IsNullOrEmpty(search)
|
||||||
|
|| (set.Metadata.Artist ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1
|
||||||
|
|| (set.Metadata.ArtistUnicode ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1
|
||||||
|
|| (set.Metadata.Title ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1
|
||||||
|
|| (set.Metadata.TitleUnicode ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1;
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
beatmapGroup.State = BeatmapGroupState.Collapsed;
|
||||||
|
if (newSelection == null || beatmapGroup.BeatmapSet.OnlineBeatmapSetID == Beatmap.BeatmapSetInfo.OnlineBeatmapSetID)
|
||||||
|
newSelection = beatmapGroup;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
beatmapGroup.State = BeatmapGroupState.Hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newSelection != null)
|
||||||
|
carousel.SelectBeatmap(newSelection.BeatmapSet.Beatmaps[0], false);
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
|
||||||
private void onDatabaseOnBeatmapSetAdded(BeatmapSetInfo s)
|
private void onDatabaseOnBeatmapSetAdded(BeatmapSetInfo s)
|
||||||
{
|
{
|
||||||
Schedule(() => addBeatmapSet(s, Game));
|
Schedule(() => addBeatmapSet(s, Game, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnEntering(GameMode last)
|
protected override void OnEntering(GameMode last)
|
||||||
@ -190,6 +238,8 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
beatmapInfoWedge.MoveToX(wedged_container_start_position.X - 50);
|
beatmapInfoWedge.MoveToX(wedged_container_start_position.X - 50);
|
||||||
beatmapInfoWedge.MoveToX(wedged_container_start_position.X, 800, EasingTypes.OutQuint);
|
beatmapInfoWedge.MoveToX(wedged_container_start_position.X, 800, EasingTypes.OutQuint);
|
||||||
|
|
||||||
|
filter.Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResuming(GameMode last)
|
protected override void OnResuming(GameMode last)
|
||||||
@ -203,6 +253,8 @@ namespace osu.Game.Screens.Select
|
|||||||
Content.FadeIn(250);
|
Content.FadeIn(250);
|
||||||
|
|
||||||
Content.ScaleTo(1, 250, EasingTypes.OutSine);
|
Content.ScaleTo(1, 250, EasingTypes.OutSine);
|
||||||
|
|
||||||
|
filter.Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnSuspending(GameMode next)
|
protected override void OnSuspending(GameMode next)
|
||||||
@ -210,6 +262,8 @@ namespace osu.Game.Screens.Select
|
|||||||
Content.ScaleTo(1.1f, 250, EasingTypes.InSine);
|
Content.ScaleTo(1.1f, 250, EasingTypes.InSine);
|
||||||
|
|
||||||
Content.FadeOut(250);
|
Content.FadeOut(250);
|
||||||
|
|
||||||
|
filter.Deactivate();
|
||||||
base.OnSuspending(next);
|
base.OnSuspending(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +273,8 @@ namespace osu.Game.Screens.Select
|
|||||||
beatmapInfoWedge.RotateTo(10, 800, EasingTypes.InQuint);
|
beatmapInfoWedge.RotateTo(10, 800, EasingTypes.InQuint);
|
||||||
|
|
||||||
Content.FadeOut(100);
|
Content.FadeOut(100);
|
||||||
|
|
||||||
|
filter.Deactivate();
|
||||||
return base.OnExiting(next);
|
return base.OnExiting(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,18 +295,15 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
private void changeBackground(WorkingBeatmap beatmap)
|
private void changeBackground(WorkingBeatmap beatmap)
|
||||||
{
|
{
|
||||||
if (beatmap == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var backgroundModeBeatmap = Background as BackgroundModeBeatmap;
|
var backgroundModeBeatmap = Background as BackgroundModeBeatmap;
|
||||||
if (backgroundModeBeatmap != null)
|
if (backgroundModeBeatmap != null)
|
||||||
{
|
{
|
||||||
backgroundModeBeatmap.Beatmap = beatmap;
|
backgroundModeBeatmap.Beatmap = beatmap;
|
||||||
// TODO: Remove this once we have non-nullable Beatmap
|
backgroundModeBeatmap.BlurTo(BACKGROUND_BLUR, 1000);
|
||||||
(Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
beatmapInfoWedge.UpdateBeatmap(beatmap);
|
if (beatmap != null)
|
||||||
|
beatmapInfoWedge.UpdateBeatmap(beatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -262,11 +315,9 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
//todo: change background in selectionChanged instead; support per-difficulty backgrounds.
|
//todo: change background in selectionChanged instead; support per-difficulty backgrounds.
|
||||||
changeBackground(beatmap);
|
changeBackground(beatmap);
|
||||||
selectBeatmap(beatmap.BeatmapInfo);
|
carousel.SelectBeatmap(beatmap.BeatmapInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectBeatmap(BeatmapInfo beatmap) => carousel.SelectBeatmap(beatmap);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// selection has been changed as the result of interaction with the carousel.
|
/// selection has been changed as the result of interaction with the carousel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -301,7 +352,7 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addBeatmapSet(BeatmapSetInfo beatmapSet, BaseGame game)
|
private void addBeatmapSet(BeatmapSetInfo beatmapSet, BaseGame game, bool select = false)
|
||||||
{
|
{
|
||||||
beatmapSet = database.GetWithChildren<BeatmapSetInfo>(beatmapSet.ID);
|
beatmapSet = database.GetWithChildren<BeatmapSetInfo>(beatmapSet.ID);
|
||||||
beatmapSet.Beatmaps.ForEach(b =>
|
beatmapSet.Beatmaps.ForEach(b =>
|
||||||
@ -314,7 +365,7 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
var beatmap = new WorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault(), beatmapSet, database);
|
var beatmap = new WorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault(), beatmapSet, database);
|
||||||
|
|
||||||
var group = new BeatmapGroup(beatmap)
|
var group = new BeatmapGroup(beatmap, beatmapSet)
|
||||||
{
|
{
|
||||||
SelectionChanged = selectionChanged,
|
SelectionChanged = selectionChanged,
|
||||||
StartRequested = b => start()
|
StartRequested = b => start()
|
||||||
@ -324,9 +375,11 @@ namespace osu.Game.Screens.Select
|
|||||||
//this likely won't scale so well, but allows us to completely async the loading flow.
|
//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
|
Task.WhenAll(group.BeatmapPanels.Select(panel => panel.Preload(game))).ContinueWith(task => Schedule(delegate
|
||||||
{
|
{
|
||||||
|
beatmapGroups.Add(group);
|
||||||
|
|
||||||
carousel.AddGroup(group);
|
carousel.AddGroup(group);
|
||||||
|
|
||||||
if (Beatmap == null)
|
if (Beatmap == null || select)
|
||||||
carousel.SelectBeatmap(beatmapSet.Beatmaps.First());
|
carousel.SelectBeatmap(beatmapSet.Beatmaps.First());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
86
osu.Game/Screens/Select/SearchTextBox.cs
Normal file
86
osu.Game/Screens/Select/SearchTextBox.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using OpenTK.Input;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Primitives;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select
|
||||||
|
{
|
||||||
|
public class SearchTextBox : TextBox
|
||||||
|
{
|
||||||
|
protected override Color4 BackgroundUnfocused => new Color4(10, 10, 10, 255);
|
||||||
|
protected override Color4 BackgroundFocused => new Color4(10, 10, 10, 255);
|
||||||
|
public Action Exit;
|
||||||
|
public bool GrabFocus = false;
|
||||||
|
|
||||||
|
private SpriteText placeholder;
|
||||||
|
|
||||||
|
protected override string InternalText
|
||||||
|
{
|
||||||
|
get { return base.InternalText; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.InternalText = value;
|
||||||
|
if (placeholder != null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(value))
|
||||||
|
placeholder.Text = "type to search";
|
||||||
|
else
|
||||||
|
placeholder.Text = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchTextBox()
|
||||||
|
{
|
||||||
|
Height = 35;
|
||||||
|
TextContainer.Padding = new MarginPadding(5);
|
||||||
|
Add(new Drawable[]
|
||||||
|
{
|
||||||
|
placeholder = new SpriteText
|
||||||
|
{
|
||||||
|
Font = @"Exo2.0-MediumItalic",
|
||||||
|
Text = "type to search",
|
||||||
|
Colour = new Color4(180, 180, 180, 255),
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Margin = new MarginPadding { Left = 10 },
|
||||||
|
},
|
||||||
|
new TextAwesome
|
||||||
|
{
|
||||||
|
Icon = FontAwesome.fa_search,
|
||||||
|
Origin = Anchor.CentreRight,
|
||||||
|
Anchor = Anchor.CentreRight,
|
||||||
|
Margin = new MarginPadding { Right = 10 },
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
if (GrabFocus && !HasFocus && IsVisible)
|
||||||
|
TriggerFocus();
|
||||||
|
base.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFocusLost(InputState state)
|
||||||
|
{
|
||||||
|
if (state.Keyboard.Keys.Any(key => key == Key.Escape))
|
||||||
|
Exit?.Invoke();
|
||||||
|
base.OnFocusLost(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Key == Key.Left || args.Key == Key.Right || args.Key == Key.Enter)
|
||||||
|
return false;
|
||||||
|
return base.OnKeyDown(state, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -68,6 +68,7 @@
|
|||||||
<Compile Include="Graphics\Cursor\CursorTrail.cs" />
|
<Compile Include="Graphics\Cursor\CursorTrail.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\BackButton.cs" />
|
<Compile Include="Graphics\UserInterface\BackButton.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\OsuTextBox.cs" />
|
<Compile Include="Graphics\UserInterface\OsuTextBox.cs" />
|
||||||
|
<Compile Include="Graphics\UserInterface\TwoLayerButton.cs" />
|
||||||
<Compile Include="Modes\Objects\HitObjectParser.cs" />
|
<Compile Include="Modes\Objects\HitObjectParser.cs" />
|
||||||
<Compile Include="Modes\Score.cs" />
|
<Compile Include="Modes\Score.cs" />
|
||||||
<Compile Include="Modes\ScoreProcesssor.cs" />
|
<Compile Include="Modes\ScoreProcesssor.cs" />
|
||||||
@ -121,6 +122,7 @@
|
|||||||
<Compile Include="Screens\Multiplayer\MatchCreate.cs" />
|
<Compile Include="Screens\Multiplayer\MatchCreate.cs" />
|
||||||
<Compile Include="Screens\Play\FailDialog.cs" />
|
<Compile Include="Screens\Play\FailDialog.cs" />
|
||||||
<Compile Include="Screens\Play\PlayerInputManager.cs" />
|
<Compile Include="Screens\Play\PlayerInputManager.cs" />
|
||||||
|
<Compile Include="Screens\Play\SkipButton.cs" />
|
||||||
<Compile Include="Screens\Select\CarouselContainer.cs" />
|
<Compile Include="Screens\Select\CarouselContainer.cs" />
|
||||||
<Compile Include="Screens\Select\MatchSongSelect.cs" />
|
<Compile Include="Screens\Select\MatchSongSelect.cs" />
|
||||||
<Compile Include="Screens\OsuGameMode.cs" />
|
<Compile Include="Screens\OsuGameMode.cs" />
|
||||||
@ -148,10 +150,10 @@
|
|||||||
<Compile Include="Graphics\Cursor\OsuCursorContainer.cs" />
|
<Compile Include="Graphics\Cursor\OsuCursorContainer.cs" />
|
||||||
<Compile Include="Graphics\Processing\RatioAdjust.cs" />
|
<Compile Include="Graphics\Processing\RatioAdjust.cs" />
|
||||||
<Compile Include="Graphics\TextAwesome.cs" />
|
<Compile Include="Graphics\TextAwesome.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\KeyCounter.cs" />
|
<Compile Include="Screens\Play\KeyCounter.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\KeyCounterKeyboard.cs" />
|
<Compile Include="Screens\Play\KeyCounterKeyboard.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\KeyCounterCollection.cs" />
|
<Compile Include="Screens\Play\KeyCounterCollection.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\KeyCounterMouse.cs" />
|
<Compile Include="Screens\Play\KeyCounterMouse.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\PercentageCounter.cs" />
|
<Compile Include="Graphics\UserInterface\PercentageCounter.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\ScoreCounter.cs" />
|
<Compile Include="Graphics\UserInterface\ScoreCounter.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\StarCounter.cs" />
|
<Compile Include="Graphics\UserInterface\StarCounter.cs" />
|
||||||
@ -237,6 +239,8 @@
|
|||||||
<Compile Include="Configuration\ScreenshotFormat.cs" />
|
<Compile Include="Configuration\ScreenshotFormat.cs" />
|
||||||
<Compile Include="Configuration\ConfineMouseMode.cs" />
|
<Compile Include="Configuration\ConfineMouseMode.cs" />
|
||||||
<Compile Include="Graphics\OsuColour.cs" />
|
<Compile Include="Graphics\OsuColour.cs" />
|
||||||
|
<Compile Include="Screens\Select\FilterControl.cs" />
|
||||||
|
<Compile Include="Screens\Select\SearchTextBox.cs" />
|
||||||
<Compile Include="Screens\Select\FooterButton.cs" />
|
<Compile Include="Screens\Select\FooterButton.cs" />
|
||||||
<Compile Include="Screens\Select\Footer.cs" />
|
<Compile Include="Screens\Select\Footer.cs" />
|
||||||
<Compile Include="Overlays\Pause\PauseButton.cs" />
|
<Compile Include="Overlays\Pause\PauseButton.cs" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user