Skip to content

Commit

Permalink
Merge pull request #2290 from andy840119/improve-singer-section
Browse files Browse the repository at this point in the history
Improve singer section.
  • Loading branch information
andy840119 authored Sep 25, 2024
2 parents b3a6f80 + 55aba1c commit b5a2647
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 172 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,5 @@ public LabelledSingerList()

public BindableList<Singer> Singers => Component.Singers;

public string SingerNamePrefix
{
get => Component.SingerNamePrefix;
set => Component.SingerNamePrefix = value;
}

protected override SingerList CreateComponent() => new();
}
126 changes: 0 additions & 126 deletions osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerDisplay.cs

This file was deleted.

158 changes: 119 additions & 39 deletions osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,23 @@
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
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.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;
using osu.Game.Rulesets.Karaoke.Beatmaps.Utils;
using osu.Game.Rulesets.Karaoke.Graphics.Cursor;
using osu.Game.Rulesets.Karaoke.Graphics.Drawables;
using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Singers.Detail;
using osuTK;

namespace osu.Game.Rulesets.Karaoke.Edit.Setup.Components;
Expand All @@ -26,27 +35,8 @@ public partial class SingerList : CompositeDrawable
{
public BindableList<Singer> Singers { get; } = new();

private string singerNamePrefix = "Singer";

public string SingerNamePrefix
{
get => singerNamePrefix;
set
{
if (singerNamePrefix == value)
return;

singerNamePrefix = value;

if (IsLoaded)
reindexItems();
}
}

private FillFlowContainer singers = null!;

private IEnumerable<SingerDisplay> singerDisplays => singers.OfType<SingerDisplay>();

[BackgroundDependencyLoader]
private void load()
{
Expand Down Expand Up @@ -82,45 +72,135 @@ private void updateSingers()
{
singers.Clear();

for (int i = 0; i < Singers.Count; ++i)
foreach (var singer in Singers)
{
// copy to avoid accesses to modified closure.
int singerIndex = i;
SingerDisplay display;

singers.Add(display = new SingerDisplay
singers.Add(new SingerDisplay
{
Current = { Value = Singers[singerIndex] },
Current = { Value = singer },
DeleteRequested = singerDeletionRequested,
});

// todo : might check does this like works because singer is object.
display.Current.BindValueChanged(singer => Singers[singerIndex] = singer.NewValue);
display.DeleteRequested += singerDeletionRequested;
}

singers.Add(new AddSingerButton
{
// todo : use better way to create singer with right id.
Action = () => Singers.Add(new Singer
{
Name = "New singer",
}),
});

reindexItems();
}

// todo : might have dialog to ask should delete singer or not if contains lyric.
private void singerDeletionRequested(SingerDisplay display) => Singers.RemoveAt(singers.IndexOf(display));
private void singerDeletionRequested(Singer singer) => Singers.Remove(singer);

private void reindexItems()
/// <summary>
/// A component which displays a singer along with related description text.
/// </summary>
private partial class SingerDisplay : CompositeDrawable, IHasCurrentValue<Singer>, IHasContextMenu, IHasPopover
{
int index = 1;
/// <summary>
/// Invoked when the user has requested the singer corresponding to this <see cref="SingerDisplay"/>.<br/>
/// to be removed from its palette.
/// </summary>
public Action<Singer>? DeleteRequested;

private readonly BindableWithCurrent<Singer> current = new();

foreach (var singerDisplay in singerDisplays)
private OsuSpriteText singerName = null!;

public Bindable<Singer> Current
{
// todo : might call singer manager to update singer id?
index += 1;
get => current.Current;
set => current.Current = value;
}

[BackgroundDependencyLoader]
private void load()
{
AutoSizeAxes = Axes.Y;
Width = 100;

InternalChild = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 10),
Children = new Drawable[]
{
new SingerCircle
{
Current = { BindTarget = Current },
},
singerName = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
},
},
};

Current.BindValueChanged(singer => singerName.Text = singer.NewValue?.Name ?? "unknown singer", true);
}

protected override bool OnClick(ClickEvent e)
{
this.ShowPopover();
return base.OnClick(e);
}

public MenuItem[] ContextMenuItems => new MenuItem[]
{
new OsuMenuItem("Edit singer info", MenuItemType.Standard, this.ShowPopover),
new OsuMenuItem("Delete", MenuItemType.Destructive, () =>
{
DeleteRequested?.Invoke(Current.Value);
}),
};

public Popover GetPopover() => new SingerEditPopover(Current.Value);

private partial class SingerCircle : Container, IHasCustomTooltip<Singer>
{
public Bindable<Singer> Current { get; } = new();

private readonly DrawableSingerAvatar singerAvatar;

public SingerCircle()
{
RelativeSizeAxes = Axes.X;
Height = 100;
CornerRadius = 50;
Masking = true;
BorderThickness = 5;

Children = new Drawable[]
{
singerAvatar = new DrawableSingerAvatar
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
},
};
}

protected override void LoadComplete()
{
base.LoadComplete();

Current.BindValueChanged(_ => updateSinger(), true);
}

private void updateSinger()
{
BorderColour = SingerUtils.GetContentColour(Current.Value);
singerAvatar.Singer = Current.Value;
}

public ITooltip<Singer> GetCustomTooltip() => new SingerToolTip();

public Singer TooltipContent => Current.Value;
}
}

Expand Down
13 changes: 12 additions & 1 deletion osu.Game.Rulesets.Karaoke/Edit/Setup/KaraokeSingerSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Rulesets.Karaoke.Beatmaps;
using osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Beatmaps;
using osu.Game.Rulesets.Karaoke.Edit.Setup.Components;
using osu.Game.Screens.Edit.Setup;

Expand All @@ -13,20 +15,29 @@ public partial class KaraokeSingerSection : SetupSection
{
public override LocalisableString Title => "Singers";

[Cached(typeof(IKaraokeBeatmapResourcesProvider))]
private KaraokeBeatmapResourcesProvider karaokeBeatmapResourcesProvider = new();

private readonly IBeatmapSingersChangeHandler changeHandler = new BeatmapSingersChangeHandler();

private LabelledSingerList singerList = null!;

[BackgroundDependencyLoader]
private void load()
{
AddInternal(karaokeBeatmapResourcesProvider);

Children = new Drawable[]
{
singerList = new LabelledSingerList
{
Label = "Singer list",
Description = "All the singers in beatmap.",
FixedLabelWidth = LABEL_WIDTH,
SingerNamePrefix = "#",
},
};

if (Beatmap.BeatmapSkin != null)
singerList.Singers.BindTo(changeHandler.Singers);
}
}

0 comments on commit b5a2647

Please sign in to comment.