@@ -9,7 +9,7 @@ namespace SwiftlyS2.Core.Menus;
99
1010internal sealed class MenuAPI : IMenuAPI , IDisposable
1111{
12- private IMenuAPI ? parent ;
12+ private ( IMenuAPI ? ParentMenu , IMenuOption ? TriggerOption ) parent ;
1313
1414 /// <summary>
1515 /// The menu manager that this menu belongs to.
@@ -42,19 +42,19 @@ internal sealed class MenuAPI : IMenuAPI, IDisposable
4242 public IMenuBuilderAPI ? Builder { get ; init ; }
4343
4444 /// <summary>
45- /// The parent menu in a hierarchical menu structure, or null if this is a top-level menu .
45+ /// The parent hierarchy information in a hierarchical menu structure.
4646 /// </summary>
47- public IMenuAPI ? Parent {
47+ public ( IMenuAPI ? ParentMenu , IMenuOption ? TriggerOption ) Parent {
4848 get => parent ;
4949 internal set {
5050 if ( parent == value )
5151 {
5252 return ;
5353 }
5454
55- if ( value == null || value == this )
55+ if ( value . ParentMenu == this )
5656 {
57- Spectre . Console . AnsiConsole . WriteException ( new ArgumentException ( $ "Parent cannot be null or self.", nameof ( value ) ) ) ;
57+ Spectre . Console . AnsiConsole . WriteException ( new ArgumentException ( $ "Parent cannot be self.", nameof ( value ) ) ) ;
5858 }
5959 else
6060 {
@@ -318,41 +318,49 @@ MenuOptionScrollStyle.LinearScroll when clampedDesiredIndex < maxVisibleItems -
318318
319319 private string BuildMenuHtml ( IPlayer player , IReadOnlyList < IMenuOption > visibleOptions , int arrowPosition , int selectedIndex , int maxOptions , int maxVisibleItems )
320320 {
321- var titleSection = Configuration . HideTitle
322- ? string . Empty
323- : string . Concat (
324- $ "<font class='fontSize-m' color='#FFFFFF'>{ Configuration . Title } </font>",
325- maxOptions > maxVisibleItems
326- ? $ "<font class='fontSize-s' color='#FFFFFF'> [{ selectedIndex + 1 } /{ maxOptions } ]</font><br><font class='fontSize-s' color='#FFFFFF'>──────────────────────────</font><br>"
327- : "<br><font class='fontSize-s' color='#FFFFFF'>──────────────────────────</font><br>"
328- ) ;
329-
330- var menuItems = visibleOptions . Select ( ( option , index ) =>
331- {
332- var prefix = index == arrowPosition
333- ? $ "<font color='#FFFFFF' class='fontSize-sm'>{ core . MenusAPI . Configuration . NavigationPrefix } </font>"
334- : "\u00A0 \u00A0 \u00A0 " ;
335- return $ "{ prefix } { option . GetDisplayText ( player , 0 ) } ";
336- } ) ;
321+ var guideLineColor = Configuration . VisualGuideLineColor ?? "#FFFFFF" ;
322+ var navigationColor = Configuration . NavigationMarkerColor ?? "#FFFFFF" ;
323+ var footerColor = Configuration . FooterColor ?? "#FF0000" ;
324+ var guideLine = $ "<font class='fontSize-s' color='{ guideLineColor } '>──────────────────────────</font>";
325+
326+ var titleSection = Configuration . HideTitle ? string . Empty : string . Concat (
327+ $ "<font class='fontSize-m' color='#FFFFFF'>{ Configuration . Title } </font>",
328+ maxOptions > maxVisibleItems
329+ ? string . Concat ( $ "<font class='fontSize-s' color='#FFFFFF'> [{ selectedIndex + 1 } /{ maxOptions } ]</font><br>", guideLine , "<br>" )
330+ : string . Concat ( "<br>" , guideLine , "<br>" )
331+ ) ;
337332
338- var footerSection = Configuration . HideFooter ? string . Empty : new Func < string > ( ( ) =>
339- {
340- var isWasd = core . MenusAPI . Configuration . InputMode == "wasd" ;
341- var moveKey = isWasd ? "W/S" : $ "{ KeybindOverrides . Move ? . ToString ( ) ?? core . MenusAPI . Configuration . ButtonsScroll . ToUpper ( ) } /{ KeybindOverrides . MoveBack ? . ToString ( ) ?? core . MenusAPI . Configuration . ButtonsScrollBack . ToUpper ( ) } ";
342- var useKey = isWasd ? "D" : ( KeybindOverrides . Select ? . ToString ( ) ?? core . MenusAPI . Configuration . ButtonsUse ) . ToUpper ( ) ;
343- var exitKey = isWasd ? "A" : ( KeybindOverrides . Exit ? . ToString ( ) ?? core . MenusAPI . Configuration . ButtonsExit ) . ToUpper ( ) ;
344- return string . Concat (
345- $ "<br>",
346- $ "<font class='fontSize-s' color='#FFFFFF'>──────────────────────────</font>",
347- $ "<br>",
348- $ "<font class='fontSize-s' color='#FFFFFF'><font color='#FF0000'>Move:</font> { moveKey } | <font color='#FF0000'>Use:</font> { useKey } | <font color='#FF0000'>Exit:</font> { exitKey } </font>"
349- ) ;
350- } ) ( ) ;
333+ var menuItems = string . Join ( "<br>" , visibleOptions . Select ( ( option , index ) => string . Concat (
334+ index == arrowPosition
335+ ? $ "<font color='{ navigationColor } ' class='fontSize-sm'>{ core . MenusAPI . Configuration . NavigationPrefix } </font>"
336+ : "\u00A0 \u00A0 \u00A0 " ,
337+ option . GetDisplayText ( player , 0 )
338+ ) ) ) ;
339+
340+ var footerSection = Configuration . HideFooter ? string . Empty :
341+ core . MenusAPI . Configuration . InputMode switch {
342+ "wasd" => string . Concat (
343+ "<br>" , guideLine , "<br>" ,
344+ "<font class='fontSize-s' color='#FFFFFF'>" ,
345+ $ "<font color='{ footerColor } '>Move:</font> W/S | ",
346+ $ "<font color='{ footerColor } '>Use:</font> D | ",
347+ $ "<font color='{ footerColor } '>Exit:</font> A",
348+ "</font>"
349+ ) ,
350+ _ => string . Concat (
351+ "<br>" , guideLine , "<br>" ,
352+ "<font class='fontSize-s' color='#FFFFFF'>" ,
353+ $ "<font color='{ footerColor } '>Move:</font> { KeybindOverrides . Move ? . ToString ( ) ?? core . MenusAPI . Configuration . ButtonsScroll . ToUpper ( ) } /{ KeybindOverrides . MoveBack ? . ToString ( ) ?? core . MenusAPI . Configuration . ButtonsScrollBack . ToUpper ( ) } | ",
354+ $ "<font color='{ footerColor } '>Use:</font> { KeybindOverrides . Select ? . ToString ( ) ?? core . MenusAPI . Configuration . ButtonsUse . ToUpper ( ) } | ",
355+ $ "<font color='{ footerColor } '>Exit:</font> { KeybindOverrides . Exit ? . ToString ( ) ?? core . MenusAPI . Configuration . ButtonsExit . ToUpper ( ) } ",
356+ "</font>"
357+ )
358+ } ;
351359
352360 return string . Concat (
353361 titleSection ,
354362 "<font color='#FFFFFF' class='fontSize-sm'>" ,
355- string . Join ( "<br>" , menuItems ) ,
363+ menuItems ,
356364 "</font>" ,
357365 footerSection
358366 ) ;
0 commit comments