Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions managed/src/SwiftlyS2.Core/Modules/Menus/Menu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ public void UseSelection( IPlayer player )
asyncButton.SetLoadingText("Processing...");
Rerender(player, true);
var closeAfter = asyncButton.CloseOnSelect;
Task.Run(async () =>
_ = Task.Run(async () =>
{
try
{
Expand Down Expand Up @@ -355,12 +355,17 @@ public void UseSelection( IPlayer player )
}

case SubmenuMenuOption submenu:
var subMenu = submenu.GetSubmenu();
if (subMenu != null)
_ = Task.Run(async () =>
{
subMenu.Parent = this;
MenuManager.OpenMenu(player, subMenu);
}
var subMenu = await submenu.GetSubmenuAsync();
if (subMenu != null && player.IsValid && MenuManager.GetMenu(player) == this)
{
subMenu.Parent = this;
MenuManager.OpenMenu(player, subMenu);
}
});
break;
default:
break;
}
}
Expand Down
82 changes: 47 additions & 35 deletions managed/src/SwiftlyS2.Core/Modules/Menus/MenuBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,133 +13,145 @@ internal class MenuBuilder : IMenuBuilder

public IMenuDesign Design => _design ??= new MenuDesign(_menu!);

public IMenuBuilder SetMenu(IMenu menu)
public IMenuBuilder SetMenu( IMenu menu )
{
_menu = menu;
return this;
}

public IMenuBuilder AddButton(string text, Action<IPlayer>? onClick = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddButton( string text, Action<IPlayer>? onClick = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new ButtonMenuOption(text, onClick, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddButton(string text, Action<IPlayer, IOption>? onClick, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddButton( string text, Action<IPlayer, IOption>? onClick, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new ButtonMenuOption(text, onClick, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddButton(string text, Action<IPlayer>? onClick, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddButton( string text, Action<IPlayer>? onClick, MenuHorizontalStyle? overflowStyle = null )
{
return AddButton(text, onClick, IMenuTextSize.Medium, overflowStyle);
}

public IMenuBuilder AddToggle(string text, bool defaultValue = false, Action<IPlayer, bool>? onToggle = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddToggle( string text, bool defaultValue = false, Action<IPlayer, bool>? onToggle = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new ToggleMenuOption(text, defaultValue, onToggle, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddToggle(string text, bool defaultValue, Action<IPlayer, IOption, bool>? onToggle, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddToggle( string text, bool defaultValue, Action<IPlayer, IOption, bool>? onToggle, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new ToggleMenuOption(text, defaultValue, onToggle, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddToggle(string text, bool defaultValue, Action<IPlayer, bool>? onToggle, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddToggle( string text, bool defaultValue, Action<IPlayer, bool>? onToggle, MenuHorizontalStyle? overflowStyle = null )
{
return AddToggle(text, defaultValue, onToggle, IMenuTextSize.Medium, overflowStyle);
}

public IMenuBuilder AddSlider(string text, float min, float max, float defaultValue, float step = 1, Action<IPlayer, float>? onChange = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddSlider( string text, float min, float max, float defaultValue, float step = 1, Action<IPlayer, float>? onChange = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new SliderMenuButton(text, min, max, defaultValue, step, onChange, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddSlider(string text, float min, float max, float defaultValue, float step, Action<IPlayer, IOption, float>? onChange, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddSlider( string text, float min, float max, float defaultValue, float step, Action<IPlayer, IOption, float>? onChange, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new SliderMenuButton(text, min, max, defaultValue, step, onChange, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddSlider(string text, float min, float max, float defaultValue, float step, Action<IPlayer, float>? onChange, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddSlider( string text, float min, float max, float defaultValue, float step, Action<IPlayer, float>? onChange, MenuHorizontalStyle? overflowStyle = null )
{
return AddSlider(text, min, max, defaultValue, step, onChange, IMenuTextSize.Medium, overflowStyle);
}

public IMenuBuilder AddAsyncButton(string text, Func<IPlayer, Task> onClickAsync, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddAsyncButton( string text, Func<IPlayer, Task> onClickAsync, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new AsyncButtonMenuOption(text, onClickAsync, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddAsyncButton(string text, Func<IPlayer, IOption, Task> onClickAsync, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddAsyncButton( string text, Func<IPlayer, IOption, Task> onClickAsync, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new AsyncButtonMenuOption(text, onClickAsync, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddAsyncButton(string text, Func<IPlayer, Task> onClickAsync, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddAsyncButton( string text, Func<IPlayer, Task> onClickAsync, MenuHorizontalStyle? overflowStyle = null )
{
return AddAsyncButton(text, onClickAsync, IMenuTextSize.Medium, overflowStyle);
}

public IMenuBuilder AddText(string text, ITextAlign alignment = ITextAlign.Left, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddText( string text, ITextAlign alignment = ITextAlign.Left, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new TextMenuOption(text, alignment, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddDynamicText(Func<string> textProvider, TimeSpan updateInterval, Action<IPlayer>? onClick = null, IMenuTextSize size = IMenuTextSize.Medium)
public IMenuBuilder AddDynamicText( Func<string> textProvider, TimeSpan updateInterval, Action<IPlayer>? onClick = null, IMenuTextSize size = IMenuTextSize.Medium )
{
_menu!.Options.Add(new DynamicMenuOption(textProvider, updateInterval, onClick, size));
_menu!.Options[^1].Menu = _menu;
return this;
}
public IMenuBuilder AddSubmenu(string text, IMenu submenu, IMenuTextSize size = IMenuTextSize.Medium)
public IMenuBuilder AddSubmenu( string text, IMenu submenu, IMenuTextSize size = IMenuTextSize.Medium )
{
_menu!.Options.Add(new SubmenuMenuOption(text, submenu, size));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddSubmenu(string text, IMenu submenu)
public IMenuBuilder AddSubmenu( string text, IMenu submenu )
{
return AddSubmenu(text, submenu, IMenuTextSize.Medium);
}

public IMenuBuilder AddSubmenu(string text, Func<IMenu> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium)
public IMenuBuilder AddSubmenu( string text, Func<IMenu> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium )
{
_menu!.Options.Add(new SubmenuMenuOption(text, submenuBuilder, size));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddSubmenu(string text, Func<IMenu> submenuBuilder)
public IMenuBuilder AddSubmenu( string text, Func<IMenu> submenuBuilder )
{
return AddSubmenu(text, submenuBuilder, IMenuTextSize.Medium);
}

public IMenuBuilder AddChoice(string text, string[] choices, string? defaultChoice = null, Action<IPlayer, string>? onChange = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddSubmenu( string text, Func<Task<IMenu>> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium )
{
_menu!.Options.Add(new SubmenuMenuOption(text, submenuBuilder, size));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddSubmenu( string text, Func<Task<IMenu>> submenuBuilder )
{
return AddSubmenu(text, submenuBuilder, IMenuTextSize.Medium);
}

public IMenuBuilder AddChoice( string text, string[] choices, string? defaultChoice = null, Action<IPlayer, string>? onChange = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new ChoiceMenuOption(text, choices, defaultChoice, onChange, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
return this;
}

public IMenuBuilder AddChoice(string text, string[] choices, string? defaultChoice, Action<IPlayer, IOption, string>? onChange, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddChoice( string text, string[] choices, string? defaultChoice, Action<IPlayer, IOption, string>? onChange, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new ChoiceMenuOption(text, choices, defaultChoice, onChange, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
Expand All @@ -159,26 +171,26 @@ public IMenuBuilder AddSeparator()
return this;
}

public IMenuBuilder AddProgressBar(string text, Func<float> progressProvider, int barWidth = 20, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddProgressBar( string text, Func<float> progressProvider, int barWidth = 20, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
{
_menu!.Options.Add(new ProgressBarMenuOption(text, progressProvider, barWidth, size, overflowStyle));
_menu!.Options[^1].Menu = _menu;
_menu!.RenderOntick = true;
return this;
}

public IMenuBuilder AddProgressBar(string text, Func<float> progressProvider, int barWidth, MenuHorizontalStyle? overflowStyle = null)
public IMenuBuilder AddProgressBar( string text, Func<float> progressProvider, int barWidth, MenuHorizontalStyle? overflowStyle = null )
{
return AddProgressBar(text, progressProvider, barWidth, IMenuTextSize.Medium, overflowStyle);
}
public IMenuBuilder WithParent(IMenu parent)
public IMenuBuilder WithParent( IMenu parent )
{
_parent = parent;
_menu!.Parent = parent;
return this;
}

public IMenuBuilder VisibleWhen(Func<IPlayer, bool> condition)
public IMenuBuilder VisibleWhen( Func<IPlayer, bool> condition )
{
if (_menu!.Options.Count > 0 && _menu!.Options[^1] is ButtonMenuOption button)
{
Expand Down Expand Up @@ -207,7 +219,7 @@ public IMenuBuilder VisibleWhen(Func<IPlayer, bool> condition)
return this;
}

public IMenuBuilder EnabledWhen(Func<IPlayer, bool> condition)
public IMenuBuilder EnabledWhen( Func<IPlayer, bool> condition )
{
if (_menu!.Options.Count > 0 && _menu!.Options[^1] is ButtonMenuOption button)
{
Expand Down Expand Up @@ -236,7 +248,7 @@ public IMenuBuilder EnabledWhen(Func<IPlayer, bool> condition)
return this;
}

public IMenuBuilder WithValidation(Func<IPlayer, bool> validation, Action<IPlayer>? onFailed = null)
public IMenuBuilder WithValidation( Func<IPlayer, bool> validation, Action<IPlayer>? onFailed = null )
{
if (_menu!.Options.Count > 0 && _menu!.Options[^1] is ButtonMenuOption button)
{
Expand Down Expand Up @@ -281,41 +293,41 @@ public IMenuBuilder CloseOnSelect()
return this;
}

public IMenuBuilder AutoClose(float seconds)
public IMenuBuilder AutoClose( float seconds )
{
_menu!.AutoCloseAfter = seconds;
return this;
}

public IMenuBuilder OverrideButtons(Action<IMenuButtonOverrides> configureOverrides)
public IMenuBuilder OverrideButtons( Action<IMenuButtonOverrides> configureOverrides )
{
configureOverrides(_menu!.ButtonOverrides!);
return this;
}

[Obsolete("Use Design.OverrideSelectButton instead")]
public IMenuBuilder OverrideSelectButton(params string[] buttonNames)
public IMenuBuilder OverrideSelectButton( params string[] buttonNames )
{
_menu!.ButtonOverrides!.Select = MenuButtonOverrides.ParseButtons(buttonNames);
return this;
}

[Obsolete("Use Design.OverrideMoveButton instead")]
public IMenuBuilder OverrideMoveButton(params string[] buttonNames)
public IMenuBuilder OverrideMoveButton( params string[] buttonNames )
{
_menu!.ButtonOverrides!.Move = MenuButtonOverrides.ParseButtons(buttonNames);
return this;
}

[Obsolete("Use Design.OverrideExitButton instead")]
public IMenuBuilder OverrideExitButton(params string[] buttonNames)
public IMenuBuilder OverrideExitButton( params string[] buttonNames )
{
_menu!.ButtonOverrides!.Exit = MenuButtonOverrides.ParseButtons(buttonNames);
return this;
}

[Obsolete("Use Design.MaxVisibleItems instead")]
public IMenuBuilder MaxVisibleItems(int count)
public IMenuBuilder MaxVisibleItems( int count )
{
if (count < 1 || count > 5)
{
Expand All @@ -337,14 +349,14 @@ public IMenuBuilder ForceFreeze()
return this;
}

public IMenuBuilder HasSound(bool hasSound)
public IMenuBuilder HasSound( bool hasSound )
{
_menu!.HasSound = hasSound;
return this;
}

[Obsolete("Use Design.SetColor instead")]
public IMenuBuilder SetColor(Color color)
public IMenuBuilder SetColor( Color color )
{
_menu!.RenderColor = color;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ internal class SubmenuMenuOption : IOption
{
public string Text { get; set; }
public IMenu? Submenu { get; set; }
public Func<IMenu>? SubmenuBuilder { get; set; }
public Func<Task<IMenu>>? SubmenuBuilderAsync { get; set; }
public Func<IPlayer, bool>? VisibilityCheck { get; set; }
public Func<IPlayer, bool>? EnabledCheck { get; set; }
public IMenuTextSize Size { get; set; }
Expand All @@ -18,31 +18,38 @@ internal class SubmenuMenuOption : IOption
public bool Visible => true;
public bool Enabled => true;

public SubmenuMenuOption(string text, IMenu? submenu = null, IMenuTextSize size = IMenuTextSize.Medium)
public SubmenuMenuOption( string text, IMenu? submenu = null, IMenuTextSize size = IMenuTextSize.Medium )
{
Text = text;
Submenu = submenu;
Size = size;
}

public SubmenuMenuOption(string text, Func<IMenu> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium)
public SubmenuMenuOption( string text, Func<IMenu> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium )
{
Text = text;
SubmenuBuilder = submenuBuilder;
SubmenuBuilderAsync = () => Task.FromResult(submenuBuilder());
Size = size;
}

public bool ShouldShow(IPlayer player)
public SubmenuMenuOption( string text, Func<Task<IMenu>> asyncSubmenuBuilder, IMenuTextSize size = IMenuTextSize.Medium )
{
Text = text;
SubmenuBuilderAsync = asyncSubmenuBuilder;
Size = size;
}

public bool ShouldShow( IPlayer player )
{
return VisibilityCheck?.Invoke(player) ?? true;
}

public bool CanInteract(IPlayer player)
public bool CanInteract( IPlayer player )
{
return EnabledCheck?.Invoke(player) ?? true;
}

public string GetDisplayText(IPlayer player, bool updateHorizontalStyle = false)
public string GetDisplayText( IPlayer player, bool updateHorizontalStyle = false )
{
var sizeClass = MenuSizeHelper.GetSizeClass(Size);

Expand All @@ -61,8 +68,18 @@ public IMenuTextSize GetTextSize()
return Size;
}

public IMenu? GetSubmenu()
public async Task<IMenu?> GetSubmenuAsync()
{
return Submenu ?? SubmenuBuilder?.Invoke();
if (Submenu != null)
{
return Submenu;
}

if (SubmenuBuilderAsync != null)
{
return await SubmenuBuilderAsync.Invoke();
}

return null;
}
}
}
Loading
Loading