From ceeb70dd17c5c8f596f22c0fe637193527a76739 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Wed, 25 Sep 2024 23:18:44 +0800 Subject: [PATCH 1/4] Move singer display class into the singer list because there's no other locaiton user this class. --- .../Edit/Setup/Components/SingerDisplay.cs | 126 ------------------ .../Edit/Setup/Components/SingerList.cs | 112 ++++++++++++++++ 2 files changed, 112 insertions(+), 126 deletions(-) delete mode 100644 osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerDisplay.cs diff --git a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerDisplay.cs b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerDisplay.cs deleted file mode 100644 index 629378b81..000000000 --- a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerDisplay.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) andy840119 . Licensed under the GPL Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.UserInterface; -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 osuTK; - -namespace osu.Game.Rulesets.Karaoke.Edit.Setup.Components; - -/// -/// A component which displays a singer along with related description text. -/// -public partial class SingerDisplay : CompositeDrawable, IHasCurrentValue -{ - /// - /// Invoked when the user has requested the singer corresponding to this .
- /// to be removed from its palette. - ///
- public event Action? DeleteRequested; - - private readonly BindableWithCurrent current = new(); - - private OsuSpriteText singerName = null!; - - public Bindable Current - { - 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 }, - DeleteRequested = () => DeleteRequested?.Invoke(this), - }, - singerName = new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }, - }, - }; - - Current.BindValueChanged(singer => singerName.Text = singer.NewValue?.Name ?? "unknown singer", true); - } - - private partial class SingerCircle : OsuClickableContainer, IHasContextMenu, IHasCustomTooltip - { - public Bindable Current { get; } = new(); - - public Action? DeleteRequested { get; init; } - - private readonly DrawableSingerAvatar singerAvatar; - - public SingerCircle() - { - RelativeSizeAxes = Axes.X; - Height = 100; - CornerRadius = 50; - Masking = true; - BorderThickness = 5; - Action = () => - { - // todo: show edit singer dialog. - }; - - 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 MenuItem[] ContextMenuItems => new MenuItem[] - { - new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke()), - }; - - public ITooltip GetCustomTooltip() => new SingerToolTip(); - - public Singer TooltipContent => Current.Value; - } -} diff --git a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs index 42542ccae..16c87ab62 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs @@ -9,12 +9,18 @@ using osu.Framework.Bindables; 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.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 osuTK; namespace osu.Game.Rulesets.Karaoke.Edit.Setup.Components; @@ -124,6 +130,112 @@ private void reindexItems() } } + /// + /// A component which displays a singer along with related description text. + /// + public partial class SingerDisplay : CompositeDrawable, IHasCurrentValue + { + /// + /// Invoked when the user has requested the singer corresponding to this .
+ /// to be removed from its palette. + ///
+ public event Action? DeleteRequested; + + private readonly BindableWithCurrent current = new(); + + private OsuSpriteText singerName = null!; + + public Bindable Current + { + 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 }, + DeleteRequested = () => DeleteRequested?.Invoke(this), + }, + singerName = new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }, + }, + }; + + Current.BindValueChanged(singer => singerName.Text = singer.NewValue?.Name ?? "unknown singer", true); + } + + private partial class SingerCircle : OsuClickableContainer, IHasContextMenu, IHasCustomTooltip + { + public Bindable Current { get; } = new(); + + public Action? DeleteRequested { get; init; } + + private readonly DrawableSingerAvatar singerAvatar; + + public SingerCircle() + { + RelativeSizeAxes = Axes.X; + Height = 100; + CornerRadius = 50; + Masking = true; + BorderThickness = 5; + Action = () => + { + // todo: show edit singer dialog. + }; + + 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 MenuItem[] ContextMenuItems => new MenuItem[] + { + new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke()), + }; + + public ITooltip GetCustomTooltip() => new SingerToolTip(); + + public Singer TooltipContent => Current.Value; + } + } + internal partial class AddSingerButton : CompositeDrawable { public Action Action From 65ecf43e928e447e7f61676110185a11824f51de Mon Sep 17 00:00:00 2001 From: andy840119 Date: Wed, 25 Sep 2024 23:41:24 +0800 Subject: [PATCH 2/4] Adjust the singer list to let it able to edit/remove the singer. --- .../Edit/Setup/Components/SingerList.cs | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs index 16c87ab62..6f62c37bc 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs @@ -7,12 +7,14 @@ 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; @@ -21,6 +23,7 @@ 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; @@ -88,20 +91,13 @@ 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 @@ -117,7 +113,7 @@ private void updateSingers() } // 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() { @@ -133,13 +129,13 @@ private void reindexItems() /// /// A component which displays a singer along with related description text. /// - public partial class SingerDisplay : CompositeDrawable, IHasCurrentValue + private partial class SingerDisplay : CompositeDrawable, IHasCurrentValue, IHasContextMenu, IHasPopover { /// /// Invoked when the user has requested the singer corresponding to this .
/// to be removed from its palette. ///
- public event Action? DeleteRequested; + public Action? DeleteRequested; private readonly BindableWithCurrent current = new(); @@ -168,7 +164,6 @@ private void load() new SingerCircle { Current = { BindTarget = Current }, - DeleteRequested = () => DeleteRequested?.Invoke(this), }, singerName = new OsuSpriteText { @@ -181,11 +176,26 @@ private void load() Current.BindValueChanged(singer => singerName.Text = singer.NewValue?.Name ?? "unknown singer", true); } - private partial class SingerCircle : OsuClickableContainer, IHasContextMenu, IHasCustomTooltip + protected override bool OnClick(ClickEvent e) { - public Bindable Current { get; } = new(); + 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 Action? DeleteRequested { get; init; } + public Popover GetPopover() => new SingerEditPopover(Current.Value); + + private partial class SingerCircle : Container, IHasCustomTooltip + { + public Bindable Current { get; } = new(); private readonly DrawableSingerAvatar singerAvatar; @@ -196,10 +206,6 @@ public SingerCircle() CornerRadius = 50; Masking = true; BorderThickness = 5; - Action = () => - { - // todo: show edit singer dialog. - }; Children = new Drawable[] { @@ -225,11 +231,6 @@ private void updateSinger() singerAvatar.Singer = Current.Value; } - public MenuItem[] ContextMenuItems => new MenuItem[] - { - new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke()), - }; - public ITooltip GetCustomTooltip() => new SingerToolTip(); public Singer TooltipContent => Current.Value; From b4f24b1bc2a3c79e59b4f3c74df8576184a29638 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 14 Sep 2024 00:24:16 +0800 Subject: [PATCH 3/4] Let the singer section able to edit the singer in the beatmap. --- .../Edit/Setup/Components/SingerList.cs | 1 - .../Edit/Setup/KaraokeSingerSection.cs | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs index 6f62c37bc..9798282ee 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs @@ -102,7 +102,6 @@ private void updateSingers() singers.Add(new AddSingerButton { - // todo : use better way to create singer with right id. Action = () => Singers.Add(new Singer { Name = "New singer", diff --git a/osu.Game.Rulesets.Karaoke/Edit/Setup/KaraokeSingerSection.cs b/osu.Game.Rulesets.Karaoke/Edit/Setup/KaraokeSingerSection.cs index 1d8008940..75f66ac61 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Setup/KaraokeSingerSection.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Setup/KaraokeSingerSection.cs @@ -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; @@ -13,11 +15,18 @@ 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 @@ -28,5 +37,8 @@ private void load() SingerNamePrefix = "#", }, }; + + if (Beatmap.BeatmapSkin != null) + singerList.Singers.BindTo(changeHandler.Singers); } } From 55aba1ca98e46c5c7bf73ad95011e2904d122db5 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Wed, 25 Sep 2024 23:55:04 +0800 Subject: [PATCH 4/4] Remove unnecessary code. --- .../Setup/Components/LabelledSingerList.cs | 6 ---- .../Edit/Setup/Components/SingerList.cs | 32 ------------------- .../Edit/Setup/KaraokeSingerSection.cs | 1 - 3 files changed, 39 deletions(-) diff --git a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/LabelledSingerList.cs b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/LabelledSingerList.cs index bfee039b0..d8d994908 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/LabelledSingerList.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/LabelledSingerList.cs @@ -16,11 +16,5 @@ public LabelledSingerList() public BindableList Singers => Component.Singers; - public string SingerNamePrefix - { - get => Component.SingerNamePrefix; - set => Component.SingerNamePrefix = value; - } - protected override SingerList CreateComponent() => new(); } diff --git a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs index 9798282ee..e64d67885 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Setup/Components/SingerList.cs @@ -35,27 +35,8 @@ public partial class SingerList : CompositeDrawable { public BindableList 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 singerDisplays => singers.OfType(); - [BackgroundDependencyLoader] private void load() { @@ -107,24 +88,11 @@ private void updateSingers() Name = "New singer", }), }); - - reindexItems(); } // todo : might have dialog to ask should delete singer or not if contains lyric. private void singerDeletionRequested(Singer singer) => Singers.Remove(singer); - private void reindexItems() - { - int index = 1; - - foreach (var singerDisplay in singerDisplays) - { - // todo : might call singer manager to update singer id? - index += 1; - } - } - /// /// A component which displays a singer along with related description text. /// diff --git a/osu.Game.Rulesets.Karaoke/Edit/Setup/KaraokeSingerSection.cs b/osu.Game.Rulesets.Karaoke/Edit/Setup/KaraokeSingerSection.cs index 75f66ac61..3a64dd23a 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Setup/KaraokeSingerSection.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Setup/KaraokeSingerSection.cs @@ -34,7 +34,6 @@ private void load() Label = "Singer list", Description = "All the singers in beatmap.", FixedLabelWidth = LABEL_WIDTH, - SingerNamePrefix = "#", }, };