Normalize all the line endings

This commit is contained in:
Dean Herbert
2018-04-13 18:19:50 +09:00
parent f99503b60c
commit 32a74f95a5
1069 changed files with 95293 additions and 95293 deletions

View File

@ -1,55 +1,55 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Screens.Select.Filter;
namespace osu.Game.Screens.Select.Carousel
{
public class CarouselBeatmap : CarouselItem
{
public readonly BeatmapInfo Beatmap;
public CarouselBeatmap(BeatmapInfo beatmap)
{
Beatmap = beatmap;
State.Value = CarouselItemState.Collapsed;
}
protected override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmap(this);
public override void Filter(FilterCriteria criteria)
{
base.Filter(criteria);
bool match = criteria.Ruleset == null || Beatmap.RulesetID == criteria.Ruleset.ID || Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps;
if (!string.IsNullOrEmpty(criteria.SearchText))
match &=
Beatmap.Metadata.SearchableTerms.Any(term => term.IndexOf(criteria.SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
Beatmap.Version.IndexOf(criteria.SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0;
Filtered.Value = !match;
}
public override int CompareTo(FilterCriteria criteria, CarouselItem other)
{
if (!(other is CarouselBeatmap otherBeatmap))
return base.CompareTo(criteria, other);
switch (criteria.Sort)
{
default:
case SortMode.Difficulty:
var ruleset = Beatmap.RulesetID.CompareTo(otherBeatmap.Beatmap.RulesetID);
if (ruleset != 0) return ruleset;
return Beatmap.StarDifficulty.CompareTo(otherBeatmap.Beatmap.StarDifficulty);
}
}
public override string ToString() => Beatmap.ToString();
}
}
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Screens.Select.Filter;
namespace osu.Game.Screens.Select.Carousel
{
public class CarouselBeatmap : CarouselItem
{
public readonly BeatmapInfo Beatmap;
public CarouselBeatmap(BeatmapInfo beatmap)
{
Beatmap = beatmap;
State.Value = CarouselItemState.Collapsed;
}
protected override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmap(this);
public override void Filter(FilterCriteria criteria)
{
base.Filter(criteria);
bool match = criteria.Ruleset == null || Beatmap.RulesetID == criteria.Ruleset.ID || Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps;
if (!string.IsNullOrEmpty(criteria.SearchText))
match &=
Beatmap.Metadata.SearchableTerms.Any(term => term.IndexOf(criteria.SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
Beatmap.Version.IndexOf(criteria.SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0;
Filtered.Value = !match;
}
public override int CompareTo(FilterCriteria criteria, CarouselItem other)
{
if (!(other is CarouselBeatmap otherBeatmap))
return base.CompareTo(criteria, other);
switch (criteria.Sort)
{
default:
case SortMode.Difficulty:
var ruleset = Beatmap.RulesetID.CompareTo(otherBeatmap.Beatmap.RulesetID);
if (ruleset != 0) return ruleset;
return Beatmap.StarDifficulty.CompareTo(otherBeatmap.Beatmap.StarDifficulty);
}
}
public override string ToString() => Beatmap.ToString();
}
}

View File

@ -1,58 +1,58 @@
// Copyright (c) 2007-2018 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 System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Beatmaps;
using osu.Game.Screens.Select.Filter;
namespace osu.Game.Screens.Select.Carousel
{
public class CarouselBeatmapSet : CarouselGroupEagerSelect
{
public IEnumerable<CarouselBeatmap> Beatmaps => InternalChildren.OfType<CarouselBeatmap>();
public BeatmapSetInfo BeatmapSet;
public CarouselBeatmapSet(BeatmapSetInfo beatmapSet)
{
BeatmapSet = beatmapSet ?? throw new ArgumentNullException(nameof(beatmapSet));
beatmapSet.Beatmaps
.Where(b => !b.Hidden)
.Select(b => new CarouselBeatmap(b))
.ForEach(AddChild);
}
protected override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmapSet(this);
public override int CompareTo(FilterCriteria criteria, CarouselItem other)
{
if (!(other is CarouselBeatmapSet otherSet))
return base.CompareTo(criteria, other);
switch (criteria.Sort)
{
default:
case SortMode.Artist:
return string.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist, StringComparison.InvariantCultureIgnoreCase);
case SortMode.Title:
return string.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title, StringComparison.InvariantCultureIgnoreCase);
case SortMode.Author:
return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.InvariantCultureIgnoreCase);
case SortMode.Difficulty:
return BeatmapSet.MaxStarDifficulty.CompareTo(otherSet.BeatmapSet.MaxStarDifficulty);
}
}
public override void Filter(FilterCriteria criteria)
{
base.Filter(criteria);
Filtered.Value = InternalChildren.All(i => i.Filtered);
}
public override string ToString() => BeatmapSet.ToString();
}
}
// Copyright (c) 2007-2018 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 System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Beatmaps;
using osu.Game.Screens.Select.Filter;
namespace osu.Game.Screens.Select.Carousel
{
public class CarouselBeatmapSet : CarouselGroupEagerSelect
{
public IEnumerable<CarouselBeatmap> Beatmaps => InternalChildren.OfType<CarouselBeatmap>();
public BeatmapSetInfo BeatmapSet;
public CarouselBeatmapSet(BeatmapSetInfo beatmapSet)
{
BeatmapSet = beatmapSet ?? throw new ArgumentNullException(nameof(beatmapSet));
beatmapSet.Beatmaps
.Where(b => !b.Hidden)
.Select(b => new CarouselBeatmap(b))
.ForEach(AddChild);
}
protected override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmapSet(this);
public override int CompareTo(FilterCriteria criteria, CarouselItem other)
{
if (!(other is CarouselBeatmapSet otherSet))
return base.CompareTo(criteria, other);
switch (criteria.Sort)
{
default:
case SortMode.Artist:
return string.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist, StringComparison.InvariantCultureIgnoreCase);
case SortMode.Title:
return string.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title, StringComparison.InvariantCultureIgnoreCase);
case SortMode.Author:
return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.InvariantCultureIgnoreCase);
case SortMode.Difficulty:
return BeatmapSet.MaxStarDifficulty.CompareTo(otherSet.BeatmapSet.MaxStarDifficulty);
}
}
public override void Filter(FilterCriteria criteria)
{
base.Filter(criteria);
Filtered.Value = InternalChildren.All(i => i.Filtered);
}
public override string ToString() => BeatmapSet.ToString();
}
}

View File

@ -1,89 +1,89 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
namespace osu.Game.Screens.Select.Carousel
{
/// <summary>
/// A group which ensures only one child is selected.
/// </summary>
public class CarouselGroup : CarouselItem
{
protected override DrawableCarouselItem CreateDrawableRepresentation() => null;
public IReadOnlyList<CarouselItem> Children => InternalChildren;
protected List<CarouselItem> InternalChildren = new List<CarouselItem>();
public override List<DrawableCarouselItem> Drawables
{
get
{
var drawables = base.Drawables;
foreach (var c in InternalChildren)
drawables.AddRange(c.Drawables);
return drawables;
}
}
public virtual void RemoveChild(CarouselItem i)
{
InternalChildren.Remove(i);
// it's important we do the deselection after removing, so any further actions based on
// State.ValueChanged make decisions post-removal.
i.State.Value = CarouselItemState.Collapsed;
}
public virtual void AddChild(CarouselItem i)
{
i.State.ValueChanged += v => ChildItemStateChanged(i, v);
InternalChildren.Add(i);
}
public CarouselGroup(List<CarouselItem> items = null)
{
if (items != null) InternalChildren = items;
State.ValueChanged += v =>
{
switch (v)
{
case CarouselItemState.Collapsed:
case CarouselItemState.NotSelected:
InternalChildren.ForEach(c => c.State.Value = CarouselItemState.Collapsed);
break;
case CarouselItemState.Selected:
InternalChildren.ForEach(c =>
{
if (c.State == CarouselItemState.Collapsed) c.State.Value = CarouselItemState.NotSelected;
});
break;
}
};
}
public override void Filter(FilterCriteria criteria)
{
base.Filter(criteria);
InternalChildren.Sort((x, y) => x.CompareTo(criteria, y));
InternalChildren.ForEach(c => c.Filter(criteria));
}
protected virtual void ChildItemStateChanged(CarouselItem item, CarouselItemState value)
{
// ensure we are the only item selected
if (value == CarouselItemState.Selected)
{
foreach (var b in InternalChildren)
{
if (item == b) continue;
b.State.Value = CarouselItemState.NotSelected;
}
State.Value = CarouselItemState.Selected;
}
}
}
}
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
namespace osu.Game.Screens.Select.Carousel
{
/// <summary>
/// A group which ensures only one child is selected.
/// </summary>
public class CarouselGroup : CarouselItem
{
protected override DrawableCarouselItem CreateDrawableRepresentation() => null;
public IReadOnlyList<CarouselItem> Children => InternalChildren;
protected List<CarouselItem> InternalChildren = new List<CarouselItem>();
public override List<DrawableCarouselItem> Drawables
{
get
{
var drawables = base.Drawables;
foreach (var c in InternalChildren)
drawables.AddRange(c.Drawables);
return drawables;
}
}
public virtual void RemoveChild(CarouselItem i)
{
InternalChildren.Remove(i);
// it's important we do the deselection after removing, so any further actions based on
// State.ValueChanged make decisions post-removal.
i.State.Value = CarouselItemState.Collapsed;
}
public virtual void AddChild(CarouselItem i)
{
i.State.ValueChanged += v => ChildItemStateChanged(i, v);
InternalChildren.Add(i);
}
public CarouselGroup(List<CarouselItem> items = null)
{
if (items != null) InternalChildren = items;
State.ValueChanged += v =>
{
switch (v)
{
case CarouselItemState.Collapsed:
case CarouselItemState.NotSelected:
InternalChildren.ForEach(c => c.State.Value = CarouselItemState.Collapsed);
break;
case CarouselItemState.Selected:
InternalChildren.ForEach(c =>
{
if (c.State == CarouselItemState.Collapsed) c.State.Value = CarouselItemState.NotSelected;
});
break;
}
};
}
public override void Filter(FilterCriteria criteria)
{
base.Filter(criteria);
InternalChildren.Sort((x, y) => x.CompareTo(criteria, y));
InternalChildren.ForEach(c => c.Filter(criteria));
}
protected virtual void ChildItemStateChanged(CarouselItem item, CarouselItemState value)
{
// ensure we are the only item selected
if (value == CarouselItemState.Selected)
{
foreach (var b in InternalChildren)
{
if (item == b) continue;
b.State.Value = CarouselItemState.NotSelected;
}
State.Value = CarouselItemState.Selected;
}
}
}
}

View File

@ -1,112 +1,112 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
namespace osu.Game.Screens.Select.Carousel
{
/// <summary>
/// A group which ensures at least one child is selected (if the group itself is selected).
/// </summary>
public class CarouselGroupEagerSelect : CarouselGroup
{
public CarouselGroupEagerSelect()
{
State.ValueChanged += v =>
{
if (v == CarouselItemState.Selected)
attemptSelection();
};
}
/// <summary>
/// The last selected item.
/// </summary>
protected CarouselItem LastSelected { get; private set; }
/// <summary>
/// We need to keep track of the index for cases where the selection is removed but we want to select a new item based on its old location.
/// </summary>
private int lastSelectedIndex;
/// <summary>
/// To avoid overhead during filter operations, we don't attempt any selections until after all
/// children have been filtered. This bool will be true during the base <see cref="Filter(FilterCriteria)"/>
/// operation.
/// </summary>
private bool filteringChildren;
public override void Filter(FilterCriteria criteria)
{
filteringChildren = true;
base.Filter(criteria);
filteringChildren = false;
attemptSelection();
}
public override void RemoveChild(CarouselItem i)
{
base.RemoveChild(i);
if (i != LastSelected)
updateSelectedIndex();
}
public override void AddChild(CarouselItem i)
{
base.AddChild(i);
attemptSelection();
}
protected override void ChildItemStateChanged(CarouselItem item, CarouselItemState value)
{
base.ChildItemStateChanged(item, value);
switch (value)
{
case CarouselItemState.Selected:
updateSelected(item);
break;
case CarouselItemState.NotSelected:
case CarouselItemState.Collapsed:
attemptSelection();
break;
}
}
private void attemptSelection()
{
if (filteringChildren) return;
// we only perform eager selection if we are a currently selected group.
if (State != CarouselItemState.Selected) return;
// we only perform eager selection if none of our children are in a selected state already.
if (Children.Any(i => i.State == CarouselItemState.Selected)) return;
PerformSelection();
}
protected virtual void PerformSelection()
{
CarouselItem nextToSelect =
Children.Skip(lastSelectedIndex).FirstOrDefault(i => !i.Filtered) ??
Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex).FirstOrDefault(i => !i.Filtered);
if (nextToSelect != null)
nextToSelect.State.Value = CarouselItemState.Selected;
else
updateSelected(null);
}
private void updateSelected(CarouselItem newSelection)
{
LastSelected = newSelection;
updateSelectedIndex();
}
private void updateSelectedIndex() => lastSelectedIndex = LastSelected == null ? 0 : Math.Max(0, InternalChildren.IndexOf(LastSelected));
}
}
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
namespace osu.Game.Screens.Select.Carousel
{
/// <summary>
/// A group which ensures at least one child is selected (if the group itself is selected).
/// </summary>
public class CarouselGroupEagerSelect : CarouselGroup
{
public CarouselGroupEagerSelect()
{
State.ValueChanged += v =>
{
if (v == CarouselItemState.Selected)
attemptSelection();
};
}
/// <summary>
/// The last selected item.
/// </summary>
protected CarouselItem LastSelected { get; private set; }
/// <summary>
/// We need to keep track of the index for cases where the selection is removed but we want to select a new item based on its old location.
/// </summary>
private int lastSelectedIndex;
/// <summary>
/// To avoid overhead during filter operations, we don't attempt any selections until after all
/// children have been filtered. This bool will be true during the base <see cref="Filter(FilterCriteria)"/>
/// operation.
/// </summary>
private bool filteringChildren;
public override void Filter(FilterCriteria criteria)
{
filteringChildren = true;
base.Filter(criteria);
filteringChildren = false;
attemptSelection();
}
public override void RemoveChild(CarouselItem i)
{
base.RemoveChild(i);
if (i != LastSelected)
updateSelectedIndex();
}
public override void AddChild(CarouselItem i)
{
base.AddChild(i);
attemptSelection();
}
protected override void ChildItemStateChanged(CarouselItem item, CarouselItemState value)
{
base.ChildItemStateChanged(item, value);
switch (value)
{
case CarouselItemState.Selected:
updateSelected(item);
break;
case CarouselItemState.NotSelected:
case CarouselItemState.Collapsed:
attemptSelection();
break;
}
}
private void attemptSelection()
{
if (filteringChildren) return;
// we only perform eager selection if we are a currently selected group.
if (State != CarouselItemState.Selected) return;
// we only perform eager selection if none of our children are in a selected state already.
if (Children.Any(i => i.State == CarouselItemState.Selected)) return;
PerformSelection();
}
protected virtual void PerformSelection()
{
CarouselItem nextToSelect =
Children.Skip(lastSelectedIndex).FirstOrDefault(i => !i.Filtered) ??
Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex).FirstOrDefault(i => !i.Filtered);
if (nextToSelect != null)
nextToSelect.State.Value = CarouselItemState.Selected;
else
updateSelected(null);
}
private void updateSelected(CarouselItem newSelection)
{
LastSelected = newSelection;
updateSelectedIndex();
}
private void updateSelectedIndex() => lastSelectedIndex = LastSelected == null ? 0 : Math.Max(0, InternalChildren.IndexOf(LastSelected));
}
}

View File

@ -1,62 +1,62 @@
// Copyright (c) 2007-2018 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.Configuration;
namespace osu.Game.Screens.Select.Carousel
{
public abstract class CarouselItem
{
public readonly BindableBool Filtered = new BindableBool();
public readonly Bindable<CarouselItemState> State = new Bindable<CarouselItemState>(CarouselItemState.NotSelected);
/// <summary>
/// This item is not in a hidden state.
/// </summary>
public bool Visible => State.Value != CarouselItemState.Collapsed && !Filtered;
public virtual List<DrawableCarouselItem> Drawables
{
get
{
var items = new List<DrawableCarouselItem>();
var self = drawableRepresentation.Value;
if (self?.IsPresent == true) items.Add(self);
return items;
}
}
protected CarouselItem()
{
drawableRepresentation = new Lazy<DrawableCarouselItem>(CreateDrawableRepresentation);
Filtered.ValueChanged += v =>
{
if (v && State == CarouselItemState.Selected)
State.Value = CarouselItemState.NotSelected;
};
}
private readonly Lazy<DrawableCarouselItem> drawableRepresentation;
protected abstract DrawableCarouselItem CreateDrawableRepresentation();
public virtual void Filter(FilterCriteria criteria)
{
}
public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => GetHashCode().CompareTo(other.GetHashCode());
}
public enum CarouselItemState
{
Collapsed,
NotSelected,
Selected,
}
}
// Copyright (c) 2007-2018 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.Configuration;
namespace osu.Game.Screens.Select.Carousel
{
public abstract class CarouselItem
{
public readonly BindableBool Filtered = new BindableBool();
public readonly Bindable<CarouselItemState> State = new Bindable<CarouselItemState>(CarouselItemState.NotSelected);
/// <summary>
/// This item is not in a hidden state.
/// </summary>
public bool Visible => State.Value != CarouselItemState.Collapsed && !Filtered;
public virtual List<DrawableCarouselItem> Drawables
{
get
{
var items = new List<DrawableCarouselItem>();
var self = drawableRepresentation.Value;
if (self?.IsPresent == true) items.Add(self);
return items;
}
}
protected CarouselItem()
{
drawableRepresentation = new Lazy<DrawableCarouselItem>(CreateDrawableRepresentation);
Filtered.ValueChanged += v =>
{
if (v && State == CarouselItemState.Selected)
State.Value = CarouselItemState.NotSelected;
};
}
private readonly Lazy<DrawableCarouselItem> drawableRepresentation;
protected abstract DrawableCarouselItem CreateDrawableRepresentation();
public virtual void Filter(FilterCriteria criteria)
{
}
public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => GetHashCode().CompareTo(other.GetHashCode());
}
public enum CarouselItemState
{
Collapsed,
NotSelected,
Selected,
}
}

View File

@ -1,176 +1,176 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Screens.Select.Carousel
{
public class DrawableCarouselBeatmap : DrawableCarouselItem, IHasContextMenu
{
private readonly BeatmapInfo beatmap;
private Sprite background;
private Action<BeatmapInfo> startRequested;
private Action<BeatmapInfo> editRequested;
private Action<BeatmapInfo> hideRequested;
private Triangles triangles;
private StarCounter starCounter;
public DrawableCarouselBeatmap(CarouselBeatmap panel) : base(panel)
{
beatmap = panel.Beatmap;
Height *= 0.60f;
}
[BackgroundDependencyLoader(true)]
private void load(SongSelect songSelect, BeatmapManager manager)
{
if (songSelect != null)
{
startRequested = songSelect.FinaliseSelection;
editRequested = songSelect.Edit;
}
if (manager != null)
hideRequested = manager.Hide;
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
},
triangles = new Triangles
{
TriangleScale = 2,
RelativeSizeAxes = Axes.Both,
ColourLight = OsuColour.FromHex(@"3a7285"),
ColourDark = OsuColour.FromHex(@"123744")
},
new FillFlowContainer
{
Padding = new MarginPadding(5),
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Children = new Drawable[]
{
new DifficultyIcon(beatmap)
{
Scale = new Vector2(1.8f),
},
new FillFlowContainer
{
Padding = new MarginPadding { Left = 5 },
Direction = FillDirection.Vertical,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
Spacing = new Vector2(4, 0),
AutoSizeAxes = Axes.Both,
Children = new[]
{
new OsuSpriteText
{
Font = @"Exo2.0-Medium",
Text = beatmap.Version,
TextSize = 20,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
},
new OsuSpriteText
{
Font = @"Exo2.0-Medium",
Text = "mapped by",
TextSize = 16,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
},
new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
Text = $"{(beatmap.Metadata ?? beatmap.BeatmapSet.Metadata).Author.Username}",
TextSize = 16,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
},
}
},
starCounter = new StarCounter
{
CountStars = (float)beatmap.StarDifficulty,
Scale = new Vector2(0.8f),
}
}
}
}
}
};
}
protected override void Selected()
{
base.Selected();
background.Colour = ColourInfo.GradientVertical(
new Color4(20, 43, 51, 255),
new Color4(40, 86, 102, 255));
triangles.Colour = Color4.White;
}
protected override void Deselected()
{
base.Deselected();
background.Colour = new Color4(20, 43, 51, 255);
triangles.Colour = OsuColour.Gray(0.5f);
}
protected override bool OnClick(InputState state)
{
if (Item.State == CarouselItemState.Selected)
startRequested?.Invoke(beatmap);
return base.OnClick(state);
}
protected override void ApplyState()
{
if (Item.State.Value != CarouselItemState.Collapsed && Alpha == 0)
starCounter.ReplayAnimation();
base.ApplyState();
}
public MenuItem[] ContextMenuItems => new MenuItem[]
{
new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested?.Invoke(beatmap)),
new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested?.Invoke(beatmap)),
new OsuMenuItem("Hide", MenuItemType.Destructive, () => hideRequested?.Invoke(beatmap)),
};
}
}
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Screens.Select.Carousel
{
public class DrawableCarouselBeatmap : DrawableCarouselItem, IHasContextMenu
{
private readonly BeatmapInfo beatmap;
private Sprite background;
private Action<BeatmapInfo> startRequested;
private Action<BeatmapInfo> editRequested;
private Action<BeatmapInfo> hideRequested;
private Triangles triangles;
private StarCounter starCounter;
public DrawableCarouselBeatmap(CarouselBeatmap panel) : base(panel)
{
beatmap = panel.Beatmap;
Height *= 0.60f;
}
[BackgroundDependencyLoader(true)]
private void load(SongSelect songSelect, BeatmapManager manager)
{
if (songSelect != null)
{
startRequested = songSelect.FinaliseSelection;
editRequested = songSelect.Edit;
}
if (manager != null)
hideRequested = manager.Hide;
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
},
triangles = new Triangles
{
TriangleScale = 2,
RelativeSizeAxes = Axes.Both,
ColourLight = OsuColour.FromHex(@"3a7285"),
ColourDark = OsuColour.FromHex(@"123744")
},
new FillFlowContainer
{
Padding = new MarginPadding(5),
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Children = new Drawable[]
{
new DifficultyIcon(beatmap)
{
Scale = new Vector2(1.8f),
},
new FillFlowContainer
{
Padding = new MarginPadding { Left = 5 },
Direction = FillDirection.Vertical,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
Spacing = new Vector2(4, 0),
AutoSizeAxes = Axes.Both,
Children = new[]
{
new OsuSpriteText
{
Font = @"Exo2.0-Medium",
Text = beatmap.Version,
TextSize = 20,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
},
new OsuSpriteText
{
Font = @"Exo2.0-Medium",
Text = "mapped by",
TextSize = 16,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
},
new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
Text = $"{(beatmap.Metadata ?? beatmap.BeatmapSet.Metadata).Author.Username}",
TextSize = 16,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
},
}
},
starCounter = new StarCounter
{
CountStars = (float)beatmap.StarDifficulty,
Scale = new Vector2(0.8f),
}
}
}
}
}
};
}
protected override void Selected()
{
base.Selected();
background.Colour = ColourInfo.GradientVertical(
new Color4(20, 43, 51, 255),
new Color4(40, 86, 102, 255));
triangles.Colour = Color4.White;
}
protected override void Deselected()
{
base.Deselected();
background.Colour = new Color4(20, 43, 51, 255);
triangles.Colour = OsuColour.Gray(0.5f);
}
protected override bool OnClick(InputState state)
{
if (Item.State == CarouselItemState.Selected)
startRequested?.Invoke(beatmap);
return base.OnClick(state);
}
protected override void ApplyState()
{
if (Item.State.Value != CarouselItemState.Collapsed && Alpha == 0)
starCounter.ReplayAnimation();
base.ApplyState();
}
public MenuItem[] ContextMenuItems => new MenuItem[]
{
new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested?.Invoke(beatmap)),
new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested?.Invoke(beatmap)),
new OsuMenuItem("Hide", MenuItemType.Destructive, () => hideRequested?.Invoke(beatmap)),
};
}
}

View File

@ -1,183 +1,183 @@
// Copyright (c) 2007-2018 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 System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Screens.Select.Carousel
{
public class DrawableCarouselBeatmapSet : DrawableCarouselItem, IHasContextMenu
{
private Action<BeatmapSetInfo> restoreHiddenRequested;
private Action<int> viewDetails;
private DialogOverlay dialogOverlay;
private readonly BeatmapSetInfo beatmapSet;
public DrawableCarouselBeatmapSet(CarouselBeatmapSet set)
: base(set)
{
beatmapSet = set.BeatmapSet;
}
[BackgroundDependencyLoader(true)]
private void load(LocalisationEngine localisation, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay)
{
if (localisation == null)
throw new ArgumentNullException(nameof(localisation));
restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore);
dialogOverlay = overlay;
if (beatmapOverlay != null)
viewDetails = beatmapOverlay.ShowBeatmapSet;
Children = new Drawable[]
{
new DelayedLoadWrapper(
new PanelBackground(manager.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()))
{
RelativeSizeAxes = Axes.Both,
OnLoadComplete = d => d.FadeInFromZero(1000, Easing.OutQuint),
}, 300
),
new FillFlowContainer
{
Direction = FillDirection.Vertical,
Padding = new MarginPadding { Top = 5, Left = 18, Right = 10, Bottom = 10 },
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new OsuSpriteText
{
Font = @"Exo2.0-BoldItalic",
Current = localisation.GetUnicodePreference(beatmapSet.Metadata.TitleUnicode, beatmapSet.Metadata.Title),
TextSize = 22,
Shadow = true,
},
new OsuSpriteText
{
Font = @"Exo2.0-SemiBoldItalic",
Current = localisation.GetUnicodePreference(beatmapSet.Metadata.ArtistUnicode, beatmapSet.Metadata.Artist),
TextSize = 17,
Shadow = true,
},
new FillFlowContainer<FilterableDifficultyIcon>
{
Margin = new MarginPadding { Top = 5 },
AutoSizeAxes = Axes.Both,
Children = ((CarouselBeatmapSet)Item).Beatmaps.Select(b => new FilterableDifficultyIcon(b)).ToList()
}
}
}
};
}
public MenuItem[] ContextMenuItems
{
get
{
List<MenuItem> items = new List<MenuItem>();
if (Item.State == CarouselItemState.NotSelected)
items.Add(new OsuMenuItem("Expand", MenuItemType.Highlighted, () => Item.State.Value = CarouselItemState.Selected));
if (beatmapSet.OnlineBeatmapSetID != null)
items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => viewDetails?.Invoke(beatmapSet.OnlineBeatmapSetID.Value)));
if (beatmapSet.Beatmaps.Any(b => b.Hidden))
items.Add(new OsuMenuItem("Restore all hidden", MenuItemType.Standard, () => restoreHiddenRequested?.Invoke(beatmapSet)));
items.Add(new OsuMenuItem("Delete", MenuItemType.Destructive, () => dialogOverlay?.Push(new BeatmapDeleteDialog(beatmapSet))));
return items.ToArray();
}
}
private class PanelBackground : BufferedContainer
{
public PanelBackground(WorkingBeatmap working)
{
CacheDrawnFrameBuffer = true;
Children = new Drawable[]
{
new BeatmapBackgroundSprite(working)
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
FillMode = FillMode.Fill,
},
new FillFlowContainer
{
Depth = -1,
Direction = FillDirection.Horizontal,
RelativeSizeAxes = Axes.Both,
// This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle
Shear = new Vector2(0.8f, 0),
Alpha = 0.5f,
Children = new[]
{
// The left half with no gradient applied
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Width = 0.4f,
},
// Piecewise-linear gradient with 3 segments to make it appear smoother
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)),
Width = 0.05f,
},
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)),
Width = 0.2f,
},
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)),
Width = 0.05f,
},
}
},
};
}
}
public class FilterableDifficultyIcon : DifficultyIcon
{
private readonly BindableBool filtered = new BindableBool();
public FilterableDifficultyIcon(CarouselBeatmap item)
: base(item.Beatmap)
{
filtered.BindTo(item.Filtered);
filtered.ValueChanged += v => Schedule(() => this.FadeTo(v ? 0.1f : 1, 100));
filtered.TriggerChange();
}
}
}
}
// Copyright (c) 2007-2018 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 System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Screens.Select.Carousel
{
public class DrawableCarouselBeatmapSet : DrawableCarouselItem, IHasContextMenu
{
private Action<BeatmapSetInfo> restoreHiddenRequested;
private Action<int> viewDetails;
private DialogOverlay dialogOverlay;
private readonly BeatmapSetInfo beatmapSet;
public DrawableCarouselBeatmapSet(CarouselBeatmapSet set)
: base(set)
{
beatmapSet = set.BeatmapSet;
}
[BackgroundDependencyLoader(true)]
private void load(LocalisationEngine localisation, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay)
{
if (localisation == null)
throw new ArgumentNullException(nameof(localisation));
restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore);
dialogOverlay = overlay;
if (beatmapOverlay != null)
viewDetails = beatmapOverlay.ShowBeatmapSet;
Children = new Drawable[]
{
new DelayedLoadWrapper(
new PanelBackground(manager.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()))
{
RelativeSizeAxes = Axes.Both,
OnLoadComplete = d => d.FadeInFromZero(1000, Easing.OutQuint),
}, 300
),
new FillFlowContainer
{
Direction = FillDirection.Vertical,
Padding = new MarginPadding { Top = 5, Left = 18, Right = 10, Bottom = 10 },
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new OsuSpriteText
{
Font = @"Exo2.0-BoldItalic",
Current = localisation.GetUnicodePreference(beatmapSet.Metadata.TitleUnicode, beatmapSet.Metadata.Title),
TextSize = 22,
Shadow = true,
},
new OsuSpriteText
{
Font = @"Exo2.0-SemiBoldItalic",
Current = localisation.GetUnicodePreference(beatmapSet.Metadata.ArtistUnicode, beatmapSet.Metadata.Artist),
TextSize = 17,
Shadow = true,
},
new FillFlowContainer<FilterableDifficultyIcon>
{
Margin = new MarginPadding { Top = 5 },
AutoSizeAxes = Axes.Both,
Children = ((CarouselBeatmapSet)Item).Beatmaps.Select(b => new FilterableDifficultyIcon(b)).ToList()
}
}
}
};
}
public MenuItem[] ContextMenuItems
{
get
{
List<MenuItem> items = new List<MenuItem>();
if (Item.State == CarouselItemState.NotSelected)
items.Add(new OsuMenuItem("Expand", MenuItemType.Highlighted, () => Item.State.Value = CarouselItemState.Selected));
if (beatmapSet.OnlineBeatmapSetID != null)
items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => viewDetails?.Invoke(beatmapSet.OnlineBeatmapSetID.Value)));
if (beatmapSet.Beatmaps.Any(b => b.Hidden))
items.Add(new OsuMenuItem("Restore all hidden", MenuItemType.Standard, () => restoreHiddenRequested?.Invoke(beatmapSet)));
items.Add(new OsuMenuItem("Delete", MenuItemType.Destructive, () => dialogOverlay?.Push(new BeatmapDeleteDialog(beatmapSet))));
return items.ToArray();
}
}
private class PanelBackground : BufferedContainer
{
public PanelBackground(WorkingBeatmap working)
{
CacheDrawnFrameBuffer = true;
Children = new Drawable[]
{
new BeatmapBackgroundSprite(working)
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
FillMode = FillMode.Fill,
},
new FillFlowContainer
{
Depth = -1,
Direction = FillDirection.Horizontal,
RelativeSizeAxes = Axes.Both,
// This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle
Shear = new Vector2(0.8f, 0),
Alpha = 0.5f,
Children = new[]
{
// The left half with no gradient applied
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Width = 0.4f,
},
// Piecewise-linear gradient with 3 segments to make it appear smoother
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)),
Width = 0.05f,
},
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)),
Width = 0.2f,
},
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)),
Width = 0.05f,
},
}
},
};
}
}
public class FilterableDifficultyIcon : DifficultyIcon
{
private readonly BindableBool filtered = new BindableBool();
public FilterableDifficultyIcon(CarouselBeatmap item)
: base(item.Beatmap)
{
filtered.BindTo(item.Filtered);
filtered.ValueChanged += v => Schedule(() => this.FadeTo(v ? 0.1f : 1, 100));
filtered.TriggerChange();
}
}
}
}

View File

@ -1,154 +1,154 @@
// Copyright (c) 2007-2018 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.Audio.Sample;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.MathUtils;
using osu.Game.Graphics;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Screens.Select.Carousel
{
public abstract class DrawableCarouselItem : Container
{
public const float MAX_HEIGHT = 80;
public override bool RemoveWhenNotAlive => false;
public override bool IsPresent => base.IsPresent || Item.Visible;
public readonly CarouselItem Item;
private Container nestedContainer;
private Container borderContainer;
private Box hoverLayer;
protected override Container<Drawable> Content => nestedContainer;
protected DrawableCarouselItem(CarouselItem item)
{
Item = item;
Height = MAX_HEIGHT;
RelativeSizeAxes = Axes.X;
Alpha = 0;
}
private SampleChannel sampleHover;
[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuColour colours)
{
InternalChild = borderContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 10,
BorderColour = new Color4(221, 255, 255, 255),
Children = new Drawable[]
{
nestedContainer = new Container
{
RelativeSizeAxes = Axes.Both,
},
hoverLayer = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
Blending = BlendingMode.Additive,
},
}
};
sampleHover = audio.Sample.Get($@"SongSelect/song-ping-variation-{RNG.Next(1, 5)}");
hoverLayer.Colour = colours.Blue.Opacity(0.1f);
}
protected override bool OnHover(InputState state)
{
sampleHover?.Play();
hoverLayer.FadeIn(100, Easing.OutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
hoverLayer.FadeOut(1000, Easing.OutQuint);
base.OnHoverLost(state);
}
public void SetMultiplicativeAlpha(float alpha) => borderContainer.Alpha = alpha;
protected override void LoadComplete()
{
base.LoadComplete();
ApplyState();
Item.Filtered.ValueChanged += _ => Schedule(ApplyState);
Item.State.ValueChanged += _ => Schedule(ApplyState);
}
protected virtual void ApplyState()
{
if (!IsLoaded) return;
switch (Item.State.Value)
{
case CarouselItemState.NotSelected:
Deselected();
break;
case CarouselItemState.Selected:
Selected();
break;
}
if (!Item.Visible)
this.FadeOut(300, Easing.OutQuint);
else
this.FadeIn(250);
}
protected virtual void Selected()
{
Item.State.Value = CarouselItemState.Selected;
borderContainer.BorderThickness = 2.5f;
borderContainer.EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = new Color4(130, 204, 255, 150),
Radius = 20,
Roundness = 10,
};
}
protected virtual void Deselected()
{
Item.State.Value = CarouselItemState.NotSelected;
borderContainer.BorderThickness = 0;
borderContainer.EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Offset = new Vector2(1),
Radius = 10,
Colour = Color4.Black.Opacity(100),
};
}
protected override bool OnClick(InputState state)
{
Item.State.Value = CarouselItemState.Selected;
return true;
}
}
}
// Copyright (c) 2007-2018 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.Audio.Sample;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.MathUtils;
using osu.Game.Graphics;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Screens.Select.Carousel
{
public abstract class DrawableCarouselItem : Container
{
public const float MAX_HEIGHT = 80;
public override bool RemoveWhenNotAlive => false;
public override bool IsPresent => base.IsPresent || Item.Visible;
public readonly CarouselItem Item;
private Container nestedContainer;
private Container borderContainer;
private Box hoverLayer;
protected override Container<Drawable> Content => nestedContainer;
protected DrawableCarouselItem(CarouselItem item)
{
Item = item;
Height = MAX_HEIGHT;
RelativeSizeAxes = Axes.X;
Alpha = 0;
}
private SampleChannel sampleHover;
[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuColour colours)
{
InternalChild = borderContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 10,
BorderColour = new Color4(221, 255, 255, 255),
Children = new Drawable[]
{
nestedContainer = new Container
{
RelativeSizeAxes = Axes.Both,
},
hoverLayer = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
Blending = BlendingMode.Additive,
},
}
};
sampleHover = audio.Sample.Get($@"SongSelect/song-ping-variation-{RNG.Next(1, 5)}");
hoverLayer.Colour = colours.Blue.Opacity(0.1f);
}
protected override bool OnHover(InputState state)
{
sampleHover?.Play();
hoverLayer.FadeIn(100, Easing.OutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
hoverLayer.FadeOut(1000, Easing.OutQuint);
base.OnHoverLost(state);
}
public void SetMultiplicativeAlpha(float alpha) => borderContainer.Alpha = alpha;
protected override void LoadComplete()
{
base.LoadComplete();
ApplyState();
Item.Filtered.ValueChanged += _ => Schedule(ApplyState);
Item.State.ValueChanged += _ => Schedule(ApplyState);
}
protected virtual void ApplyState()
{
if (!IsLoaded) return;
switch (Item.State.Value)
{
case CarouselItemState.NotSelected:
Deselected();
break;
case CarouselItemState.Selected:
Selected();
break;
}
if (!Item.Visible)
this.FadeOut(300, Easing.OutQuint);
else
this.FadeIn(250);
}
protected virtual void Selected()
{
Item.State.Value = CarouselItemState.Selected;
borderContainer.BorderThickness = 2.5f;
borderContainer.EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = new Color4(130, 204, 255, 150),
Radius = 20,
Roundness = 10,
};
}
protected virtual void Deselected()
{
Item.State.Value = CarouselItemState.NotSelected;
borderContainer.BorderThickness = 0;
borderContainer.EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Offset = new Vector2(1),
Radius = 10,
Colour = Color4.Black.Opacity(100),
};
}
protected override bool OnClick(InputState state)
{
Item.State.Value = CarouselItemState.Selected;
return true;
}
}
}