private void CreateMenuItems() { var addElement = new UIMenuListScrollerItem <string>("Add Element", "", new[] { "Rect", "Text" }); addElement.Activated += (m, s) => { ElementMenu menu = addElement.Index switch { 0 => new RectMenu(rectId++), 1 => new TextMenu(textId++), _ => throw new NotImplementedException(), }; var bindItem = new UIMenuItem(menu.Name); AddItem(bindItem); BindMenuToItem(menu, bindItem); elements.Add(menu.Element); }; AddItems(addElement); }
private void CreateMenuItems() { { var visible = new UIMenuCheckboxItem("Visible", false); visible.CheckboxEvent += (s, v) => { if (v) { tbPool.Add(text, progressBar, checkpoints, icons); } else { tbPool.Clear(); } }; AddItem(visible); } UIMenuItem textBindItem = new UIMenuItem("Text", $"Demonstrates the ~b~{nameof(TextTimerBar)}~s~ class."); UIMenuItem progressBarBindItem = new UIMenuItem("Progress Bar", $"Demonstrates the ~b~{nameof(BarTimerBar)}~s~ class."); UIMenuItem checkpointsBindItem = new UIMenuItem("Checkpoints", $"Demonstrates the ~b~{nameof(CheckpointsTimerBar)}~s~ class."); UIMenuItem iconsBindItem = new UIMenuItem("Icons", $"Demonstrates the ~b~{nameof(IconsTimerBar)}~s~ class."); UIMenu textMenu = new UIMenu(TitleText, SubtitleText + ": TEXT"); UIMenu progressBarMenu = new UIMenu(TitleText, SubtitleText + ": PROGRESS BAR"); UIMenu checkpointsMenu = new UIMenu(TitleText, SubtitleText + ": CHECKPOINTS"); UIMenu iconsMenu = new UIMenu(TitleText, SubtitleText + ": ICONS"); Plugin.Pool.Add(textMenu, progressBarMenu, checkpointsMenu, iconsMenu); AddItems(textBindItem, progressBarBindItem, checkpointsBindItem, iconsBindItem); BindMenuToItem(textMenu, textBindItem); BindMenuToItem(progressBarMenu, progressBarBindItem); BindMenuToItem(checkpointsMenu, checkpointsBindItem); BindMenuToItem(iconsMenu, iconsBindItem); // text { var textItem = new UIMenuItem(nameof(TextTimerBar.Text), "Select to edit the timer bar text.") .WithTextEditing(() => text.Text, s => text.Text = s); textMenu.AddItem(textItem); AddCommonMenuItems(textMenu, text); } // progressBar { var percentage = new UIMenuNumericScrollerItem <float>(nameof(BarTimerBar.Percentage), "", 0.0f, 1.0f, 0.01f) .WithTextEditing(); percentage.Value = progressBar.Percentage; percentage.IndexChanged += (s, o, n) => { progressBar.Percentage = percentage.Value; }; var foreground = NewColorsItem(nameof(BarTimerBar.ForegroundColor), ""); progressBar.ForegroundColor = (foreground.SelectedItem = HudColor.Red).GetColor(); foreground.IndexChanged += (s, o, n) => { progressBar.ForegroundColor = foreground.SelectedItem.GetColor(); }; var background = NewColorsItem(nameof(BarTimerBar.BackgroundColor), ""); progressBar.BackgroundColor = (background.SelectedItem = HudColor.RedDark).GetColor(); background.IndexChanged += (s, o, n) => { progressBar.BackgroundColor = background.SelectedItem.GetColor(); }; var markers = new UIMenuCheckboxItem("Markers", false); markers.CheckboxEvent += (m, v) => { if (v) { progressBar.Markers.Add(new TimerBarMarker(0.25f)); progressBar.Markers.Add(new TimerBarMarker(0.50f)); progressBar.Markers.Add(new TimerBarMarker(0.75f)); } else { progressBar.Markers.Clear(); } }; progressBarMenu.AddItems(percentage, foreground, background, markers); progressBarMenu.WithFastScrollingOn(percentage); AddCommonMenuItems(progressBarMenu, progressBar); } // checkpoints { var state = new UIMenuListScrollerItem <TimerBarCheckpointState>("State", "", (TimerBarCheckpointState[])Enum.GetValues(typeof(TimerBarCheckpointState))); state.IndexChanged += (s, o, n) => { foreach (var cp in checkpoints.Checkpoints) { cp.State = state.SelectedItem; } }; var crossedOut = new UIMenuCheckboxItem("Crossed Out", false); crossedOut.CheckboxEvent += (s, v) => { foreach (var cp in checkpoints.Checkpoints) { cp.IsCrossedOut = v; } }; var color = NewColorsItem("Color", ""); color.IndexChanged += (s, o, n) => { Color c = color.SelectedItem.GetColor(); foreach (var cp in checkpoints.Checkpoints) { cp.Color = c; } }; var num = new UIMenuNumericScrollerItem <int>("Number of Checkpoints", "", 0, 16, 1) .WithTextEditing(); num.Value = checkpoints.Checkpoints.Count; num.IndexChanged += (s, o, n) => { if (checkpoints.Checkpoints.Count > num.Value) { checkpoints.Checkpoints = checkpoints.Checkpoints.Take(num.Value).ToList(); } else { Color c = color.SelectedItem.GetColor(); for (int i = checkpoints.Checkpoints.Count; i < num.Value; i++) { var cp = new TimerBarCheckpoint(); cp.Color = c; cp.IsCrossedOut = crossedOut.Checked; cp.State = state.SelectedItem; checkpoints.Checkpoints.Add(cp); } } }; checkpointsMenu.AddItems(num, state, crossedOut, color); AddCommonMenuItems(checkpointsMenu, checkpoints); } // icons { var num = new UIMenuNumericScrollerItem <int>("Number of Icons", "", 0, 8, 1).WithTextEditing(); var type = new UIMenuListScrollerItem <(string Name, Func <TimerBarIcon> Creator)>("Type", "", new (string, Func <TimerBarIcon>)[]
public ButtonMenu(InstructionalButton button) : base(Plugin.MenuTitle, "INSTRUCTIONAL BUTTONS: " + button.Text.ToUpper()) { Plugin.Pool.Add(this); this.button = button; var text = new UIMenuItem("Text", "") { Enabled = true } .WithTextEditing(() => buttonText, s => { buttonText = s; this.button.Button = s; InstructionalButtons.Update(); }); var control = new UIMenuListScrollerItem <GameControl>("Control", "", (GameControl[])System.Enum.GetValues(typeof(GameControl))) { Enabled = false, SelectedItem = buttonControl }; control.IndexChanged += (s, o, n) => { buttonControl = control.SelectedItem; this.button.Button = control.SelectedItem; InstructionalButtons.Update(); }; var rawId = new UIMenuNumericScrollerItem <uint>("Raw ID", "", 0, 2048, 1) { Enabled = false, Value = buttonRawId }.WithTextEditing(); rawId.IndexChanged += (s, o, n) => { buttonRawId = rawId.Value; this.button.Button = rawId.Value; InstructionalButtons.Update(); }; var instructionalKey = new UIMenuListScrollerItem <InstructionalKey>("Instructional Key", "", ((InstructionalKey[])System.Enum.GetValues(typeof(InstructionalKey))).Distinct()) { Enabled = false, SelectedItem = buttonInstructionalKey }; instructionalKey.IndexChanged += (s, o, n) => { buttonInstructionalKey = instructionalKey.SelectedItem; this.button.Button = instructionalKey.SelectedItem; InstructionalButtons.Update(); }; var type = new UIMenuListScrollerItem <string>("Type", "", new[] { "Text", "Control", "Raw ID", "Instructional Key" }); type.IndexChanged += (s, o, n) => { const int TextIdx = 0, ControlIdx = 1, RawIdIdx = 2, InstructionalKeyIdx = 3; text.Enabled = n == TextIdx; control.Enabled = n == ControlIdx; rawId.Enabled = n == RawIdIdx; instructionalKey.Enabled = n == InstructionalKeyIdx; this.button.Button = n switch { TextIdx => buttonText, ControlIdx => buttonControl, RawIdIdx => buttonRawId, InstructionalKeyIdx => buttonInstructionalKey, _ => buttonText }; InstructionalButtons.Update(); }; var remove = new UIMenuItem("Remove"); remove.Activated += (m, s) => { UIMenu parentMenu = ParentMenu; UIMenuItem parentItem = ParentItem; Close(); parentMenu.ReleaseMenuFromItem(parentItem); parentMenu.RemoveItemAt(parentMenu.MenuItems.IndexOf(parentItem)); Plugin.Pool.Remove(this); parentMenu.InstructionalButtons.Buttons.Remove(button); parentMenu.InstructionalButtons.Update(); foreach (UIMenu child in parentMenu.Children.Values) { child.InstructionalButtons.Buttons.Remove(this.button); child.InstructionalButtons.Update(); } }; AddItems(type, text, control, rawId, instructionalKey, remove); } }
private static void Main() { // create the pool that handles drawing and processing the menus pool = new MenuPool(); // create the main menu mainMenu = new UIMenu("RAGENativeUI", "EXAMPLE"); // create the menu items { var cb = new UIMenuCheckboxItem("Checkbox", false, "A checkbox menu item."); // show a message when toggling the checkbox cb.CheckboxEvent += (item, isChecked) => Game.DisplaySubtitle($"The checkbox is {(isChecked ? "" : "~r~not~s~ ")}checked"); var spawnCar = new UIMenuItem("Spawn car", "Spawns a random car after 5 seconds."); spawnCar.Activated += (menu, item) => { // disable the item so the user cannot activate it again until the car has spawned spawnCar.Enabled = false; GameFiber.StartNew(() => { // 5 second countdown for (int sec = 5; sec > 0; sec--) { // show the countdown in the menu description mainMenu.DescriptionOverride = $"The car will spawn in ~b~{sec}~s~ second(s)."; GameFiber.Sleep(1000); // sleep for 1 second } // remove the countdown from the description mainMenu.DescriptionOverride = null; // spawn the random car new Vehicle(m => m.IsCar, Game.LocalPlayer.Character.GetOffsetPositionFront(5.0f)).Dismiss(); // wait a bit and re-enable the item GameFiber.Sleep(500); spawnCar.Enabled = true; }); }; // a numeric scroller from -50 to 50 in intervals of 5 var numbers = new UIMenuNumericScrollerItem <int>("Numbers", "A numeric scroller menu item.", -50, 50, 5); numbers.IndexChanged += (item, oldIndex, newIndex) => Game.DisplaySubtitle($"{oldIndex} -> {newIndex}| Selected number = {numbers.Value}"); // a list scroller with strings var strings = new UIMenuListScrollerItem <string>("Strings", "A list scroller menu item with strings.", new[] { "Hello", "World", "Foo", "Bar" }); strings.IndexChanged += (item, oldIndex, newIndex) => Game.DisplaySubtitle($"{oldIndex} -> {newIndex}| Selected string = {strings.SelectedItem}"); // item in which the user can choose the cash amount to give or remove when activated var cash = new UIMenuNumericScrollerItem <int>("Cash", "Give or remove cash.", -10_000, 10_000, 50); // custom formatter that adds the dollar sign, the positive/negative sign and // colors it green when positive and red when negative (and keeps it the default color when selected, for readability) cash.Formatter = n => cash.Selected ? $"{n:+$#;-$#;$0}" : $"{n:~g~+$#;~r~-$#;$0}"; // reformat the item when the menu selection changes since the formatter depends on the Selected property, and it could have changed mainMenu.OnIndexChange += (menu, itemIndex) => cash.Reformat(); cash.Activated += (menu, item) => { if (cash.Value == 0) { return; } // give cash to the player uint stat = Game.LocalPlayer.Model.Hash switch { 0x0D7114C9 /*player_zero*/ => Game.GetHashKey("SP0_TOTAL_CASH"), 0x9B22DBAF /*player_one*/ => Game.GetHashKey("SP1_TOTAL_CASH"), 0x9B810FA2 /*player_two*/ => Game.GetHashKey("SP2_TOTAL_CASH"), _ => 0 }; if (stat != 0) { NativeFunction.Natives.STAT_GET_INT(stat, out int totalCash, -1); NativeFunction.Natives.STAT_SET_INT(stat, totalCash + cash.Value, true); } }; // add the items to the menu mainMenu.AddItems(cb, spawnCar, numbers, strings, cash); } // create a child menu UIMenu childMenu = new UIMenu("RAGENativeUI", "CHILD MENU"); // create a new item in the main menu and bind the child menu to it { UIMenuItem bindItem = new UIMenuItem("Go to child menu"); mainMenu.AddItem(bindItem); mainMenu.BindMenuToItem(childMenu, bindItem); bindItem.RightBadge = UIMenuItem.BadgeStyle.Star; mainMenu.OnIndexChange += (menu, index) => mainMenu.MenuItems[index].RightBadge = UIMenuItem.BadgeStyle.None; } // create the child menu items childMenu.AddItems(Enumerable.Range(1, 50).Select(i => new UIMenuItem($"Item #{i}"))); ConfirmationMenu exitMenu = new ConfirmationMenu(mainMenu.TitleText, "EXIT", "Are you sure you want to exit this example menu?"); exitMenu.Back += (s, e) => mainMenu.Visible = true; mainMenu.OnMenuClose += s => exitMenu.Visible = true; // add all the menus to the pool pool.Add(mainMenu, childMenu, exitMenu); // start the fiber which will handle drawing and processing the menus GameFiber.StartNew(ProcessMenus); // continue with the plugin... Game.Console.Print($" Press {KeyBinding} to open the menu."); Game.DisplayHelp($"Press ~{KeyBinding.GetInstructionalId()}~ to open the menu."); }