Skip to content

Commit

Permalink
feat: OnDrawMethod for dynamic values
Browse files Browse the repository at this point in the history
  • Loading branch information
oscar-wos committed Jun 24, 2024
1 parent f18a1a1 commit e5df5e9
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
- name: Extract version and create tag
id: extract_version
run: |
version="1.0.0"
version="1.0.1"
echo "Version found: $version"
git config --global user.email "[email protected]"
git config --global user.name "GitHub Actions"
Expand Down
117 changes: 114 additions & 3 deletions Example/Example.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using Menu;
using Menu.Enums;

Expand All @@ -11,6 +12,25 @@ public class Example : BasePlugin
public override string ModuleVersion => "1.0.0";
public Menu.Menu Menu { get; } = new();

private readonly Dictionary<CCSPlayerController, MenuBase> _dynamicMenu = new();

public Example()
{
global::Menu.Menu.OnDrawMenu += (_, menuEvent) =>
{
var controller = menuEvent.Controller;

if (!_dynamicMenu.TryGetValue(controller, out var dynamicMenu))
return;

if (menuEvent.Menu != dynamicMenu)
return;

var dynamicValue = (DynamicValue)dynamicMenu.Items[0].Head!;
dynamicValue.Position = controller.PlayerPawn.Value!.AbsOrigin!;
};
}

public override void Load(bool isReload)
{
AddCommand("css_test", "", (controller, _) =>
Expand Down Expand Up @@ -109,7 +129,7 @@ public override void Load(bool isReload)
break;

case ButtonType.Select:
CustomSelect(controller);
CustomSelect(controller, new Vector(0, 0, 0));
break;
}

Expand Down Expand Up @@ -139,12 +159,45 @@ public override void Load(bool isReload)
}
});
});

AddCommand("css_test1", "", (controller, _) =>
{
if (controller == null || !controller.IsValid)
return;

var dynamicMenu = new MenuBase(new MenuValue("Dynamic Menu") { Prefix = "<font class=\"fontSize-L\">", Suffix = "<font class=\"fontSize-sm\">" });

var dynamicItem = new MenuItem(MenuItemType.Text, new DynamicValue(""));
dynamicMenu.AddItem(dynamicItem);

var saveButton = new MenuItem(MenuItemType.Button, [new MenuValue("Save")]);
dynamicMenu.AddItem(saveButton);

_dynamicMenu[controller] = dynamicMenu;

Menu.SetMenu(controller, dynamicMenu, (buttons, menu, _) =>
{
if (buttons != MenuButtons.Select)
return;

if (menu.Option != 0)
return;

if (menu.Option == 0)
{
var dynamicValue = (DynamicValue)menu.Items[0].Head!;
Console.WriteLine($"{dynamicValue}");

CustomSelect(controller, dynamicValue.Position);
}
});
});
}

private void CustomSelect(CCSPlayerController controller)
private void CustomSelect(CCSPlayerController controller, Vector pos)
{
// Since it's a sub menu setting Prefix will not affect the title as it inherits from Menu[0], Suffix will still work
var subMenu = new MenuBase(new MenuValue("Sub Menu") { Prefix = "<font class=\"fontSize-XXXL\">", Suffix = "<font class=\"fontSize-s\">" }) ;
var subMenu = new MenuBase(new MenuValue("Sub Menu") { Prefix = "<font class=\"fontSize-XXXL\">", Suffix = "<font class=\"fontSize-m\">" }) ;

var options = new List<MenuValue>
{
Expand All @@ -160,6 +213,9 @@ private void CustomSelect(CCSPlayerController controller)
subMenu.AddItem(itemOptions);
subMenu.AddItem(new MenuItem(MenuItemType.Bool));

subMenu.AddItem(new MenuItem(MenuItemType.Spacer));
subMenu.AddItem(new MenuItem(MenuItemType.Text, new MenuValue($"Saving: {pos.X} {pos.Y} {pos.Z}")));

// Menu.AddMenu() to add to the stack (sub-menu)
Menu.AddMenu(controller, subMenu, (buttons, menu, item) =>
{
Expand All @@ -176,6 +232,51 @@ private void CustomSelect(CCSPlayerController controller)
Console.WriteLine($"Bool: {item.Data[0]}");
});
}

private void BuildMenu(CCSPlayerController controller)
{
// Create a Menu object which holds all data
var mainMenu = new MenuBase(new MenuValue("Main Menu") { Prefix = "<font class=\"fontSize-L\">", Suffix = "<font class=\"fontSize-sm\">" });

// Can add custom formatting, MenuValue[2] Cursor, MenuValue[2] Selector, MenuValue[2] Bool, MenuValue[4] Slider, MenuValue[1] Input
var cursor = new MenuValue[2]
{
// MenuValue is the fundamental building block of everything in the Menu - MenuValue.Value, MenuValue.Prefix, MenuValue.Suffix
new("--> ") { Prefix = "<font color=\"#FFFFFF\">", Suffix = "<font color=\"#FFFFFF\">" },
new(" <--") { Prefix = "<font color=\"#FFFFFF\">", Suffix = "<font color=\"#FFFFFF\">" }
};

mainMenu.Cursor = cursor;

// Let's add a simple text field to the menu, each (row) is a MenuItem which holds data for that (row)
// Again MenuValue is the fundamental building block of everything in the Menu - MenuValue.Value, MenuValue.Prefix, MenuValue.Suffix

var textItem = new MenuValue("Welcome to the new menu!");

// Let's modify the prefix and suffix of the textItem

textItem.Prefix = "<font color=\"#FF0000\">";
textItem.Suffix = "<font color=\"#FFFFFF\">";

// Simplified

textItem = new MenuValue("Welcome to the new menu!")
{
Prefix = "<font color=\"#FF0000\">",
Suffix = "<font color=\"#FFFFFF\">"
};

var simpleTextItem = new MenuItem(MenuItemType.Text, textItem);

// Now let's add the textItem to the menu
mainMenu.AddItem(simpleTextItem);

// And let's add to the global stack to print to the player
Menu.SetMenu(controller, mainMenu, (buttons, menu, item) => { });

// The library automatically handles the deposition of the menu
// Using Tab (Scoreboard) exists the menu, and Ctrl (Duck) will go back to the previous menu
}
}

public class PlayerValue(string value, int? id) : MenuValue(value)
Expand All @@ -195,4 +296,14 @@ public enum ButtonType
Search,
Find,
Select
}

public class DynamicValue(string value) : MenuValue(value)
{
public Vector Position { get; set; } = new(0, 0, 0);

public override string ToString()
{
return $"{Prefix}x: {Position.X} y: {Position.Y} z: {Position.Z}{Suffix}";
}
}
15 changes: 15 additions & 0 deletions src/IMenuEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using CounterStrikeSharp.API.Core;

namespace Menu;

public interface IMenuEvent
{

}

public class MenuEvent(CCSPlayerController controller, MenuBase menu, MenuItem? selectedItem) : IMenuEvent
{
public CCSPlayerController Controller { get; set; } = controller;
public MenuBase Menu { get; set; } = menu;
public MenuItem? SelectedItem { get; set; } = selectedItem;
}
36 changes: 35 additions & 1 deletion src/Menu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class Menu
private static readonly Timer Timer = new(0.1f, TimerRepeat, TimerFlags.REPEAT);
private static readonly SayEvent OnSay = new("say", OnSayEvent);
private static readonly SayEvent OnSayTeam = new("say_team", OnSayEvent);
public static event EventHandler<MenuEvent>? OnDrawMenu;

private static void OnSayEvent(CCSPlayerController? controller, string message)
{
Expand All @@ -27,6 +28,11 @@ private static void OnSayEvent(CCSPlayerController? controller, string message)
menu.AcceptInput = false;
}

protected static void RaiseDrawMenu(CCSPlayerController controller, MenuBase menu, MenuItem? selectedItem)
{
OnDrawMenu?.Invoke(null, new MenuEvent(controller, menu, selectedItem));
}

private static void TimerRepeat()
{
foreach (var (controller, menus) in Menus)
Expand Down Expand Up @@ -148,6 +154,7 @@ private static void TimerRepeat()

menu.AcceptButtons = buttons == 0;
DrawMenu(controller, menu, selectedItem);
RaiseDrawMenu(controller, menu, selectedItem);
}
}

Expand Down Expand Up @@ -259,7 +266,10 @@ private static string FormatValues(MenuBase menu, MenuItem menuItem, MenuItem se

private static string FormatString(MenuBase menu, MenuItem menuItem, int index)
{
var menuValue = menuItem.Values![index];
if (menuItem.Values == null)
return "";

var menuValue = menuItem.Values[index];

if (menuItem.Type != MenuItemType.ChoiceBool)
return menuValue.ToString();
Expand Down Expand Up @@ -333,4 +343,28 @@ public void AddMenu(CCSPlayerController controller, MenuBase menu, Action<MenuBu
menu.Callback = callback;
Menus[controller].Push(menu);
}

public void ClearMenus(CCSPlayerController controller)
{
Menus.Remove(controller);
}

public void PopMenu(CCSPlayerController controller, MenuBase? menu = null)
{
if (!Menus.TryGetValue(controller, out var value))
return;

if (menu != null && value.Peek() != menu)
return;

value.Pop();
}

public bool IsCurrentMenu(CCSPlayerController controller, MenuBase menu)
{
if (!Menus.TryGetValue(controller, out var value))
return false;

return value.Peek() == menu;
}
}

0 comments on commit e5df5e9

Please sign in to comment.