mirror of
https://github.com/ppy/osu.git
synced 2025-01-14 02:13:21 +08:00
Refactoring part 4.
This commit is contained in:
parent
97a7f16ab7
commit
580cf93147
119
osu.Game/Overlays/Music/FilterControl.cs
Normal file
119
osu.Game/Overlays/Music/FilterControl.cs
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Select;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Music
|
||||
{
|
||||
internal class FilterControl : Container
|
||||
{
|
||||
public readonly FilterTextBox Search;
|
||||
|
||||
public FilterControl()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(0f, 10f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Search = new FilterTextBox
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 40,
|
||||
},
|
||||
new CollectionsDropdown<PlaylistCollection>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Items = new[] { new KeyValuePair<string, PlaylistCollection>(@"All", PlaylistCollection.All) },
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public class FilterTextBox : SearchTextBox
|
||||
{
|
||||
protected override Color4 BackgroundUnfocused => OsuColour.FromHex(@"222222");
|
||||
protected override Color4 BackgroundFocused => OsuColour.FromHex(@"222222");
|
||||
|
||||
public FilterTextBox()
|
||||
{
|
||||
Masking = true;
|
||||
CornerRadius = 5;
|
||||
}
|
||||
}
|
||||
|
||||
private class CollectionsDropdown<T> : OsuDropdown<T>
|
||||
{
|
||||
protected override DropdownHeader CreateHeader() => new CollectionsHeader { AccentColour = AccentColour };
|
||||
protected override Menu CreateMenu() => new CollectionsMenu();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
AccentColour = colours.Gray6;
|
||||
}
|
||||
|
||||
private class CollectionsHeader : OsuDropdownHeader
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
BackgroundColour = colours.Gray4;
|
||||
}
|
||||
|
||||
public CollectionsHeader()
|
||||
{
|
||||
CornerRadius = 5;
|
||||
Height = 30;
|
||||
Icon.TextSize = 14;
|
||||
Icon.Margin = new MarginPadding(0);
|
||||
Foreground.Padding = new MarginPadding { Top = 4, Bottom = 4, Left = 10, Right = 10 };
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Colour = Color4.Black.Opacity(0.3f),
|
||||
Radius = 3,
|
||||
Offset = new Vector2(0f, 1f),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class CollectionsMenu : OsuMenu
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Background.Colour = colours.Gray4;
|
||||
}
|
||||
|
||||
public CollectionsMenu()
|
||||
{
|
||||
CornerRadius = 5;
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Colour = Color4.Black.Opacity(0.3f),
|
||||
Radius = 3,
|
||||
Offset = new Vector2(0f, 1f),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,395 +0,0 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Select;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Music
|
||||
{
|
||||
public class PlaylistController : OverlayContainer
|
||||
{
|
||||
private const float transition_duration = 600;
|
||||
|
||||
private const float playlist_height = 510;
|
||||
|
||||
private FilterControl filter;
|
||||
private Playlist list;
|
||||
|
||||
public BeatmapSetInfo[] List => list.Sets;
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public Action<BeatmapSetInfo, int> OnSelect;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game, OsuColour colours, BeatmapDatabase beatmaps)
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CornerRadius = 5,
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Colour = Color4.Black.Opacity(40),
|
||||
Radius = 5,
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = colours.Gray3,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
list = new Playlist
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 },
|
||||
},
|
||||
filter = new FilterControl
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding(10),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
list.Sets = beatmaps.GetAllWithChildren<BeatmapSetInfo>().ToArray();
|
||||
list.OnSelect = (beatmap, index) => OnSelect?.Invoke(beatmap, index);
|
||||
|
||||
beatmapBacking.BindTo(game.Beatmap);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
beatmapBacking.ValueChanged += b => list.Current = b?.BeatmapSetInfo;
|
||||
beatmapBacking.TriggerChange();
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
filter.Search.HoldFocus = true;
|
||||
filter.Search.TriggerFocus();
|
||||
|
||||
|
||||
ResizeTo(new Vector2(1, playlist_height), transition_duration, EasingTypes.OutQuint);
|
||||
FadeIn(transition_duration, EasingTypes.OutQuint);
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
filter.Search.HoldFocus = false;
|
||||
filter.Search.TriggerFocusLost();
|
||||
|
||||
ResizeTo(new Vector2(1, 0), transition_duration, EasingTypes.OutQuint);
|
||||
FadeOut(transition_duration);
|
||||
}
|
||||
|
||||
private class FilterControl : Container
|
||||
{
|
||||
public readonly FilterTextBox Search;
|
||||
|
||||
public FilterControl()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(0f, 10f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Search = new FilterTextBox
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 40,
|
||||
},
|
||||
new CollectionsDropdown<PlaylistCollection>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Items = new[] { new KeyValuePair<string, PlaylistCollection>(@"All", PlaylistCollection.All) },
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public class FilterTextBox : SearchTextBox
|
||||
{
|
||||
protected override Color4 BackgroundUnfocused => OsuColour.FromHex(@"222222");
|
||||
protected override Color4 BackgroundFocused => OsuColour.FromHex(@"222222");
|
||||
|
||||
public FilterTextBox()
|
||||
{
|
||||
Masking = true;
|
||||
CornerRadius = 5;
|
||||
}
|
||||
}
|
||||
|
||||
private class CollectionsDropdown<T> : OsuDropdown<T>
|
||||
{
|
||||
protected override DropdownHeader CreateHeader() => new CollectionsHeader { AccentColour = AccentColour };
|
||||
protected override Menu CreateMenu() => new CollectionsMenu();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
AccentColour = colours.Gray6;
|
||||
}
|
||||
|
||||
private class CollectionsHeader : OsuDropdownHeader
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
BackgroundColour = colours.Gray4;
|
||||
}
|
||||
|
||||
public CollectionsHeader()
|
||||
{
|
||||
CornerRadius = 5;
|
||||
Height = 30;
|
||||
Icon.TextSize = 14;
|
||||
Icon.Margin = new MarginPadding(0);
|
||||
Foreground.Padding = new MarginPadding { Top = 4, Bottom = 4, Left = 10, Right = 10 };
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Colour = Color4.Black.Opacity(0.3f),
|
||||
Radius = 3,
|
||||
Offset = new Vector2(0f, 1f),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class CollectionsMenu : OsuMenu
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Background.Colour = colours.Gray4;
|
||||
}
|
||||
|
||||
public CollectionsMenu()
|
||||
{
|
||||
CornerRadius = 5;
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Colour = Color4.Black.Opacity(0.3f),
|
||||
Radius = 3,
|
||||
Offset = new Vector2(0f, 1f),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Playlist : Container
|
||||
{
|
||||
private readonly FillFlowContainer<PlaylistItem> items;
|
||||
|
||||
private BeatmapSetInfo[] sets = { };
|
||||
public BeatmapSetInfo[] Sets
|
||||
{
|
||||
get
|
||||
{
|
||||
return sets;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == sets) return;
|
||||
sets = value;
|
||||
|
||||
List<PlaylistItem> newItems = new List<PlaylistItem>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
newItems.Add(new PlaylistItem(value[i], i)
|
||||
{
|
||||
OnSelect = itemSelected,
|
||||
});
|
||||
}
|
||||
|
||||
items.Children = newItems;
|
||||
}
|
||||
}
|
||||
|
||||
private void itemSelected(BeatmapSetInfo arg1, int arg2) => OnSelect?.Invoke(arg1, arg2);
|
||||
|
||||
public Action<BeatmapSetInfo, int> OnSelect;
|
||||
|
||||
private BeatmapSetInfo current;
|
||||
public BeatmapSetInfo Current
|
||||
{
|
||||
get { return current; }
|
||||
set
|
||||
{
|
||||
if (value == current) return;
|
||||
current = value;
|
||||
|
||||
foreach (PlaylistItem s in items.Children)
|
||||
s.Current = s.RepresentedSet.ID == value.ID;
|
||||
}
|
||||
}
|
||||
|
||||
public Playlist()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new ScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
items = new FillFlowContainer<PlaylistItem>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private class PlaylistItem : Container
|
||||
{
|
||||
private const float fade_duration = 100;
|
||||
private Color4 currentColour;
|
||||
|
||||
private readonly TextAwesome icon;
|
||||
private readonly IEnumerable<OsuSpriteText> title, artist;
|
||||
|
||||
public readonly int Index;
|
||||
public readonly BeatmapSetInfo RepresentedSet;
|
||||
public Action<BeatmapSetInfo, int> OnSelect;
|
||||
|
||||
private bool current;
|
||||
public bool Current
|
||||
{
|
||||
get { return current; }
|
||||
set
|
||||
{
|
||||
if (value == current) return;
|
||||
current = value;
|
||||
|
||||
Flush(true);
|
||||
foreach (OsuSpriteText t in title)
|
||||
t.FadeColour(Current ? currentColour : Color4.White, fade_duration);
|
||||
}
|
||||
}
|
||||
|
||||
public PlaylistItem(BeatmapSetInfo set, int index)
|
||||
{
|
||||
Index = index;
|
||||
RepresentedSet = set;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Padding = new MarginPadding { Top = 3, Bottom = 3 };
|
||||
|
||||
FillFlowContainer<OsuSpriteText> textContainer = new FillFlowContainer<OsuSpriteText>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Left = 20 },
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
};
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
icon = new TextAwesome
|
||||
{
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
TextSize = 12,
|
||||
Icon = FontAwesome.fa_bars,
|
||||
Alpha = 0f,
|
||||
Margin = new MarginPadding { Left = 5 },
|
||||
Padding = new MarginPadding { Top = 2 },
|
||||
},
|
||||
textContainer,
|
||||
};
|
||||
|
||||
textContainer.Add(title = splitText(RepresentedSet.Metadata.Title, 16, @"Exo2.0-Regular", new MarginPadding(0)));
|
||||
textContainer.Add(artist = splitText(RepresentedSet.Metadata.Artist, 14, @"Exo2.0-Bold", new MarginPadding { Top = 1 }));
|
||||
}
|
||||
|
||||
private IEnumerable<OsuSpriteText> splitText(string text, int textSize, string font, MarginPadding padding)
|
||||
{
|
||||
List<OsuSpriteText> sprites = new List<OsuSpriteText>();
|
||||
|
||||
foreach (string w in text.Split(' '))
|
||||
{
|
||||
sprites.Add(new OsuSpriteText
|
||||
{
|
||||
TextSize = textSize,
|
||||
Font = font,
|
||||
Text = w,
|
||||
Padding = padding,
|
||||
});
|
||||
}
|
||||
|
||||
return sprites;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
foreach (OsuSpriteText t in artist)
|
||||
t.Colour = colours.Gray9;
|
||||
|
||||
icon.Colour = colours.Gray5;
|
||||
currentColour = colours.Yellow;
|
||||
}
|
||||
|
||||
protected override bool OnHover(Framework.Input.InputState state)
|
||||
{
|
||||
icon.FadeIn(fade_duration);
|
||||
|
||||
return base.OnHover(state);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(Framework.Input.InputState state)
|
||||
{
|
||||
icon.FadeOut(fade_duration);
|
||||
}
|
||||
|
||||
protected override bool OnClick(Framework.Input.InputState state)
|
||||
{
|
||||
OnSelect?.Invoke(RepresentedSet, Index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//todo: placeholder
|
||||
public enum PlaylistCollection
|
||||
{
|
||||
All
|
||||
}
|
||||
}
|
127
osu.Game/Overlays/Music/PlaylistItem.cs
Normal file
127
osu.Game/Overlays/Music/PlaylistItem.cs
Normal file
@ -0,0 +1,127 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Music
|
||||
{
|
||||
internal class PlaylistItem : Container
|
||||
{
|
||||
private const float fade_duration = 100;
|
||||
private Color4 currentColour;
|
||||
|
||||
private readonly TextAwesome icon;
|
||||
private readonly IEnumerable<OsuSpriteText> title, artist;
|
||||
|
||||
public readonly int Index;
|
||||
public readonly BeatmapSetInfo RepresentedSet;
|
||||
public Action<BeatmapSetInfo, int> OnSelect;
|
||||
|
||||
private bool current;
|
||||
public bool Current
|
||||
{
|
||||
get { return current; }
|
||||
set
|
||||
{
|
||||
if (value == current) return;
|
||||
current = value;
|
||||
|
||||
Flush(true);
|
||||
foreach (OsuSpriteText t in title)
|
||||
t.FadeColour(Current ? currentColour : Color4.White, fade_duration);
|
||||
}
|
||||
}
|
||||
|
||||
public PlaylistItem(BeatmapSetInfo set, int index)
|
||||
{
|
||||
Index = index;
|
||||
RepresentedSet = set;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Padding = new MarginPadding { Top = 3, Bottom = 3 };
|
||||
|
||||
FillFlowContainer<OsuSpriteText> textContainer = new FillFlowContainer<OsuSpriteText>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Left = 20 },
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
};
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
icon = new TextAwesome
|
||||
{
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
TextSize = 12,
|
||||
Icon = FontAwesome.fa_bars,
|
||||
Alpha = 0f,
|
||||
Margin = new MarginPadding { Left = 5 },
|
||||
Padding = new MarginPadding { Top = 2 },
|
||||
},
|
||||
textContainer,
|
||||
};
|
||||
|
||||
textContainer.Add(title = splitText(RepresentedSet.Metadata.Title, 16, @"Exo2.0-Regular", new MarginPadding(0)));
|
||||
textContainer.Add(artist = splitText(RepresentedSet.Metadata.Artist, 14, @"Exo2.0-Bold", new MarginPadding { Top = 1 }));
|
||||
}
|
||||
|
||||
private IEnumerable<OsuSpriteText> splitText(string text, int textSize, string font, MarginPadding padding)
|
||||
{
|
||||
List<OsuSpriteText> sprites = new List<OsuSpriteText>();
|
||||
|
||||
foreach (string w in text.Split(' '))
|
||||
{
|
||||
sprites.Add(new OsuSpriteText
|
||||
{
|
||||
TextSize = textSize,
|
||||
Font = font,
|
||||
Text = w,
|
||||
Padding = padding,
|
||||
});
|
||||
}
|
||||
|
||||
return sprites;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
foreach (OsuSpriteText t in artist)
|
||||
t.Colour = colours.Gray9;
|
||||
|
||||
icon.Colour = colours.Gray5;
|
||||
currentColour = colours.Yellow;
|
||||
}
|
||||
|
||||
protected override bool OnHover(Framework.Input.InputState state)
|
||||
{
|
||||
icon.FadeIn(fade_duration);
|
||||
|
||||
return base.OnHover(state);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(Framework.Input.InputState state)
|
||||
{
|
||||
icon.FadeOut(fade_duration);
|
||||
}
|
||||
|
||||
protected override bool OnClick(Framework.Input.InputState state)
|
||||
{
|
||||
OnSelect?.Invoke(RepresentedSet, Index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
70
osu.Game/Overlays/Music/PlaylistList.cs
Normal file
70
osu.Game/Overlays/Music/PlaylistList.cs
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Overlays.Music
|
||||
{
|
||||
internal class PlaylistList : Container
|
||||
{
|
||||
private readonly FillFlowContainer<PlaylistItem> items;
|
||||
|
||||
public IEnumerable<BeatmapSetInfo> BeatmapSets
|
||||
{
|
||||
set
|
||||
{
|
||||
List<PlaylistItem> newItems = new List<PlaylistItem>();
|
||||
|
||||
int i = 0;
|
||||
foreach (var item in value)
|
||||
{
|
||||
newItems.Add(new PlaylistItem(item, i++)
|
||||
{
|
||||
OnSelect = (b, idx) => OnSelect?.Invoke(b, idx)
|
||||
});
|
||||
}
|
||||
|
||||
items.Children = newItems;
|
||||
}
|
||||
}
|
||||
|
||||
public Action<BeatmapSetInfo, int> OnSelect;
|
||||
|
||||
private BeatmapSetInfo current;
|
||||
public BeatmapSetInfo Current
|
||||
{
|
||||
get { return current; }
|
||||
set
|
||||
{
|
||||
if (value == current) return;
|
||||
current = value;
|
||||
|
||||
foreach (PlaylistItem s in items.Children)
|
||||
s.Current = s.RepresentedSet.ID == value.ID;
|
||||
}
|
||||
}
|
||||
|
||||
public PlaylistList()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new ScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
items = new FillFlowContainer<PlaylistItem>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
165
osu.Game/Overlays/Music/PlaylistOverlay.cs
Normal file
165
osu.Game/Overlays/Music/PlaylistOverlay.cs
Normal file
@ -0,0 +1,165 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Extensions;
|
||||
|
||||
namespace osu.Game.Overlays.Music
|
||||
{
|
||||
public class PlaylistOverlay : OverlayContainer
|
||||
{
|
||||
private const float transition_duration = 600;
|
||||
|
||||
private const float playlist_height = 510;
|
||||
|
||||
private FilterControl filter;
|
||||
private PlaylistList list;
|
||||
|
||||
private TrackManager trackManager;
|
||||
private BeatmapDatabase beatmaps;
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
protected IEnumerable<BeatmapSetInfo> BeatmapSets;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game, BeatmapDatabase beatmaps, OsuColour colours)
|
||||
{
|
||||
this.beatmaps = beatmaps;
|
||||
trackManager = game.Audio.Track;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CornerRadius = 5,
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Colour = Color4.Black.Opacity(40),
|
||||
Radius = 5,
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = colours.Gray3,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
list = new PlaylistList
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 },
|
||||
OnSelect = itemSelected,
|
||||
},
|
||||
filter = new FilterControl
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding(10),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
list.BeatmapSets = BeatmapSets = beatmaps.GetAllWithChildren<BeatmapSetInfo>().ToList();
|
||||
|
||||
beatmapBacking.BindTo(game.Beatmap);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
beatmapBacking.ValueChanged += b => list.Current = b?.BeatmapSetInfo;
|
||||
beatmapBacking.TriggerChange();
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
filter.Search.HoldFocus = true;
|
||||
filter.Search.TriggerFocus();
|
||||
|
||||
|
||||
ResizeTo(new Vector2(1, playlist_height), transition_duration, EasingTypes.OutQuint);
|
||||
FadeIn(transition_duration, EasingTypes.OutQuint);
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
filter.Search.HoldFocus = false;
|
||||
filter.Search.TriggerFocusLost();
|
||||
|
||||
ResizeTo(new Vector2(1, 0), transition_duration, EasingTypes.OutQuint);
|
||||
FadeOut(transition_duration);
|
||||
}
|
||||
|
||||
private void itemSelected(BeatmapSetInfo set, int index)
|
||||
{
|
||||
if (set.ID == (beatmapBacking.Value?.BeatmapSetInfo?.ID ?? -1))
|
||||
{
|
||||
beatmapBacking.Value?.Track?.Seek(0);
|
||||
return;
|
||||
}
|
||||
|
||||
playSpecified(set.Beatmaps[0]);
|
||||
}
|
||||
|
||||
public void PlayPrevious()
|
||||
{
|
||||
var currentID = beatmapBacking.Value?.BeatmapSetInfo.ID ?? -1;
|
||||
var available = BeatmapSets.Reverse();
|
||||
|
||||
var playable = available.SkipWhile(b => b.ID != currentID).Skip(1).FirstOrDefault() ?? available.FirstOrDefault();
|
||||
|
||||
if (playable != null)
|
||||
playSpecified(playable.Beatmaps[0]);
|
||||
}
|
||||
|
||||
public void PlayNext()
|
||||
{
|
||||
var currentID = beatmapBacking.Value?.BeatmapSetInfo.ID ?? -1;
|
||||
var available = BeatmapSets;
|
||||
|
||||
var playable = available.SkipWhile(b => b.ID != currentID).Skip(1).FirstOrDefault() ?? available.FirstOrDefault();
|
||||
|
||||
if (playable != null)
|
||||
playSpecified(playable.Beatmaps[0]);
|
||||
}
|
||||
|
||||
private void playSpecified(BeatmapInfo info)
|
||||
{
|
||||
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking);
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
var track = beatmapBacking.Value.Track;
|
||||
trackManager.SetExclusive(track);
|
||||
track.Start();
|
||||
}).ContinueWith(task => Schedule(task.ThrowIfFaulted), TaskContinuationOptions.OnlyOnFaulted);
|
||||
}
|
||||
}
|
||||
|
||||
//todo: placeholder
|
||||
public enum PlaylistCollection
|
||||
{
|
||||
All
|
||||
}
|
||||
}
|
@ -2,15 +2,12 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -23,7 +20,6 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using System.Linq;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Overlays.Music;
|
||||
|
||||
@ -47,13 +43,8 @@ namespace osu.Game.Overlays
|
||||
|
||||
private SpriteText title, artist;
|
||||
|
||||
private PlaylistController playlist;
|
||||
private PlaylistOverlay playlist;
|
||||
|
||||
private List<BeatmapSetInfo> playList;
|
||||
private int playListIndex = -1;
|
||||
|
||||
private TrackManager trackManager;
|
||||
private BeatmapDatabase beatmaps;
|
||||
private LocalisationEngine localisation;
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
@ -89,10 +80,8 @@ namespace osu.Game.Overlays
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game, BeatmapDatabase beatmaps, OsuColour colours, LocalisationEngine localisation)
|
||||
private void load(OsuGameBase game, OsuColour colours, LocalisationEngine localisation)
|
||||
{
|
||||
this.beatmaps = beatmaps;
|
||||
trackManager = game.Audio.Track;
|
||||
this.localisation = localisation;
|
||||
|
||||
Children = new Drawable[]
|
||||
@ -105,22 +94,10 @@ namespace osu.Game.Overlays
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
playlist = new PlaylistController
|
||||
playlist = new PlaylistOverlay
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Y = player_height + 10,
|
||||
//todo: this is the logic I expect, but maybe not others
|
||||
OnSelect = (set, index) =>
|
||||
{
|
||||
if (set.ID == (current?.BeatmapSetInfo?.ID ?? -1))
|
||||
{
|
||||
current?.Track?.Seek(0);
|
||||
return;
|
||||
}
|
||||
|
||||
playListIndex = index;
|
||||
playSpecified(set.Beatmaps[0]);
|
||||
},
|
||||
},
|
||||
playerContainer = new Container
|
||||
{
|
||||
@ -229,8 +206,6 @@ namespace osu.Game.Overlays
|
||||
beatmapBacking.ValueChanged += beatmapChanged;
|
||||
beatmapBacking.TriggerChange();
|
||||
|
||||
playList = playlist.List.ToList();
|
||||
|
||||
base.LoadComplete();
|
||||
}
|
||||
|
||||
@ -263,14 +238,8 @@ namespace osu.Game.Overlays
|
||||
|
||||
if (track == null)
|
||||
{
|
||||
if (playList.Count > 0)
|
||||
{
|
||||
playSpecified(playList.First().Beatmaps[0]);
|
||||
|
||||
if ((track = current?.Track) == null) return;
|
||||
}
|
||||
else
|
||||
return;
|
||||
playlist.PlayNext();
|
||||
return;
|
||||
}
|
||||
|
||||
if (track.IsRunning)
|
||||
@ -281,42 +250,14 @@ namespace osu.Game.Overlays
|
||||
|
||||
private void prev()
|
||||
{
|
||||
if (playList.Count == 0) return;
|
||||
if (beatmapBacking != null && playList.Count == 1) return;
|
||||
|
||||
int n = playListIndex - 1;
|
||||
if (n < 0)
|
||||
n = playList.Count - 1;
|
||||
|
||||
playSpecified(playList[n].Beatmaps[0], TransformDirection.Prev);
|
||||
playListIndex = n;
|
||||
queuedDirection = TransformDirection.Prev;
|
||||
playlist.PlayPrevious();
|
||||
}
|
||||
|
||||
private void next()
|
||||
{
|
||||
if (playList.Count == 0) return;
|
||||
if (beatmapBacking != null && playList.Count == 1) return;
|
||||
|
||||
int n = playListIndex + 1;
|
||||
if (n >= playList.Count)
|
||||
n = 0;
|
||||
|
||||
playSpecified(playList[n].Beatmaps[0]);
|
||||
playListIndex = n;
|
||||
}
|
||||
|
||||
private void playSpecified(BeatmapInfo info, TransformDirection direction = TransformDirection.Next)
|
||||
{
|
||||
queuedDirection = direction;
|
||||
|
||||
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking);
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
var track = beatmapBacking.Value.Track;
|
||||
trackManager.SetExclusive(track);
|
||||
track.Start();
|
||||
}).ContinueWith(task => Schedule(task.ThrowIfFaulted), TaskContinuationOptions.OnlyOnFaulted);
|
||||
queuedDirection = TransformDirection.Next;
|
||||
playlist.PlayNext();
|
||||
}
|
||||
|
||||
private WorkingBeatmap current;
|
||||
|
@ -75,6 +75,9 @@
|
||||
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
|
||||
<Compile Include="Beatmaps\DifficultyCalculator.cs" />
|
||||
<Compile Include="Online\API\Requests\PostMessageRequest.cs" />
|
||||
<Compile Include="Overlays\Music\FilterControl.cs" />
|
||||
<Compile Include="Overlays\Music\PlaylistItem.cs" />
|
||||
<Compile Include="Overlays\Music\PlaylistList.cs" />
|
||||
<Compile Include="Overlays\Toolbar\ToolbarChatButton.cs" />
|
||||
<Compile Include="Rulesets\Beatmaps\BeatmapConverter.cs" />
|
||||
<Compile Include="Rulesets\Beatmaps\BeatmapProcessor.cs" />
|
||||
@ -421,7 +424,7 @@
|
||||
<Compile Include="Screens\Select\BeatmapDetailArea.cs" />
|
||||
<Compile Include="Graphics\UserInterface\OsuTabControlCheckbox.cs" />
|
||||
<Compile Include="Screens\Select\BeatmapDetailAreaTabControl.cs" />
|
||||
<Compile Include="Overlays\Music\PlaylistController.cs" />
|
||||
<Compile Include="Overlays\Music\PlaylistOverlay.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(SolutionDir)\osu-framework\osu.Framework\osu.Framework.csproj">
|
||||
|
Loading…
Reference in New Issue
Block a user