TomGrobbe / MenuAPI

FiveM C# Menu API. Designed specifically as a replacement of NativeUI for vMenu. Full safezone scaling supported, both left and right aligned menus supported.
https://docs.vespura.com/mapi
61 stars 46 forks source link

OnMenuClose.. close too much #15

Closed manups4e closed 5 years ago

manups4e commented 5 years ago

i'm here agin to piss you off again XD i don't know if this is intentional but i think so.. whenever i call OnMenuCLose.. the code in the event is executed even if i'm passing to a submenu.. for example the problem is like.. if i use OnMenuClose to delete a scripted camera that should still exist with the submenu.. the camera gets deleted when passing to the submenu

TomGrobbe commented 5 years ago

@manups4e simply check if the submenu is open in the close event before deleting the camera.

manups4e commented 5 years ago

i tried.. it still get executed.. i give you an example,

    BincoPant.OnMenuClose += async (_menu) =>
    {
        if (!Pant.Visible)
        {
            await UpdateDress(Eventi.Player.getCurrentChar().dressing);
            NegozioAbitiClient.Esci();
        }
    };

the code is still executed even when i go to Pant subMenu

TomGrobbe commented 5 years ago

@manups4e That's because the menu is closed before the next one is opened, to prevent 2 menus being open at the same time. Simply add a small delay.

manups4e commented 5 years ago

umm ok i'll try

manups4e commented 5 years ago

still the same with await Delay(100) and await Delay(200) edit... even with Delay(500) it waits and then execute the code even with submenu opened

TomGrobbe commented 5 years ago

Are you sure the "Pant" menu is the one you're opening?

manups4e commented 5 years ago

yup

this is the menu complete

        public static async void BincoPant(List<Singolo> Completi, string anim)
        {
            MenuItem ciao = new MenuItem("");
            MenuItem ciaone = new MenuItem("");
            Menu menusuperfigo = new Menu("");
            MenuController.EnableMenuToggleKeyOnController = false;
            MenuController.MenuToggleKey = (Control)(-21);
            MenuController.MenuAlignment = MenuController.MenuAlignmentOption.Left;
            Menu BincoPant = new Menu(" ", "~y~Benvenuti da Binco's!")
            {
                HeaderTexture = Main.Textures["Binco"]
            };
            MenuController.AddMenu(BincoPant);
            BincoPant.CustomInstructionalButtons = new List<Menu.InstructionalButton> { new Menu.InstructionalButton("~INPUT_FRONTEND_LT~", "Zoom") };
            Game.PlayerPed.BlockPermanentEvents = true;
            SetPedAlternateMovementAnim(Game.PlayerPed.Handle, 0, anim, "try_trousers_base", 4.0f, true);
            await Game.PlayerPed.Task.PlayAnimation(anim, "try_trousers_base", 8f, -8f, -1, AnimationFlags.Loop, 0);
            var completi = Completi.OrderBy(x => x.Price).ToList();
            int money = 0;
            int mod = 0;
            int text = 0;
            foreach (var v in completi)
            {
                Menu Pant = new Menu(" ", v.Title)
                {
                    HeaderTexture = Main.Textures["Binco"]
                };
                Pant.CustomInstructionalButtons = new List<Menu.InstructionalButton> { new Menu.InstructionalButton("~INPUT_FRONTEND_LT~", "Zoom") };
                MenuItem pan = new MenuItem(v.Title, v.Description);
                BincoPant.AddMenuItem(pan);
                MenuController.AddSubmenu(BincoPant, Pant);
                MenuController.BindMenuItem(BincoPant, Pant, pan);
                foreach (var texture in v.Text)
                {
                    MenuItem pant = new MenuItem("Modello " + v.Text.IndexOf(texture));
                    Pant.AddMenuItem(pant);
                    money = v.Price + (v.Text.IndexOf(texture) * 47);
                    if (Eventi.Player.getMoney() >= money)
                        pan.Label = "~g~$" + money;
                    else
                    {
                        if (Eventi.Player.getBank() >= money)
                            pant.Label = "~g~$" + money;
                        else
                            pant.Label = "~r~$" + money;
                    }
                    if (v.Modello == Eventi.Player.getCurrentChar().dressing.ComponentDrawables[4])
                    {
                        pan.RightIcon = MenuItem.Icon.CLOTHING; // cambiare con la collezione di abiti
                        ciao = pan;
                    }
                    if (Eventi.Player.getCurrentChar().dressing.ComponentTextures[4] == texture)
                    {
                        pant.RightIcon = MenuItem.Icon.CLOTHING; // cambiare con la collezione di abiti
                        ciaone = pant;
                    }
                }

                Pant.OnIndexChange += async (_menu, _oldItem, _newItem, _oldIndex, _newIndex) =>
                {
                    string random = GetRandomAnim(anim, false);
                    SetPedComponentVariation(PlayerPedId(), 4, v.Modello, v.Text[_newIndex], 2);
                    await Game.PlayerPed.Task.PlayAnimation(anim, random, 4f, -2f, -1, AnimationFlags.None, 0);
                    mod = v.Modello;
                    text = v.Text[_newIndex];
                };
                Pant.OnMenuClose += async (_menu) =>
                {
                    await UpdateDress(Eventi.Player.getCurrentChar().dressing);
                };
                Pant.OnItemSelect += async (_menu, _item, _index) =>
                {
                    string m = string.Empty;
                    int val = 0;
                    for (int i = 0; i < _item.Label.Length; i++)
                    {
                        if (Char.IsDigit(_item.Label[i]))
                            m += _item.Label[i];
                    }

                    if (m.Length > 0)
                        val = int.Parse(m);

                    if (Eventi.Player.getMoney() >= val)
                    {
                        TriggerServerEvent("lprp:abiti:compra", val, 1);
                        Eventi.Player.getCurrentChar().dressing.ComponentDrawables[4] = mod;
                        Eventi.Player.getCurrentChar().dressing.ComponentTextures[4] = text;
                        TriggerServerEvent("lprp:updateCurChar", "chardressing", JsonConvert.SerializeObject(Eventi.Player.getCurrentChar().dressing));
                        ciao.RightIcon = MenuItem.Icon.NONE;
                        ciao = BincoPant.GetCurrentMenuItem();
                        ciao.RightIcon = MenuItem.Icon.CLOTHING;
                        ciaone.RightIcon = MenuItem.Icon.NONE;
                        ciaone = _item;
                        ciaone.RightIcon = MenuItem.Icon.CLOTHING;
                        Func.ShowNotification("Hai speso ~g~" + val + "$~w~, in contanti");
                    }
                    else
                    {
                        if (Eventi.Player.getBank() >= val)
                        {
                            TriggerServerEvent("lprp:abiti:compra", val, 2);
                            Eventi.Player.getCurrentChar().dressing.ComponentDrawables[4] = mod;
                            Eventi.Player.getCurrentChar().dressing.ComponentTextures[4] = text;
                            TriggerServerEvent("lprp:updateCurChar", "chardressing", JsonConvert.SerializeObject(Eventi.Player.getCurrentChar().dressing));
                            ciao.RightIcon = MenuItem.Icon.NONE;
                            ciao = BincoPant.GetCurrentMenuItem();
                            ciao.RightIcon = MenuItem.Icon.CLOTHING;
                            ciaone.RightIcon = MenuItem.Icon.NONE;
                            ciaone = _item;
                            ciaone.RightIcon = MenuItem.Icon.CLOTHING;
                            Func.ShowNotification("Hai speso ~g~" + val + "$~w~, con carta di credito");
                        }
                        else
                            Func.ShowNotification("Non hai i soldi per questo abito!", Func.NotificationColor.Red, true);
                    }
                };
                BincoPant.OnMenuClose += async (_menu) =>
                {
                    await Delay(500);
                    if (!Pant.Visible)
                    {
                        await UpdateDress(Eventi.Player.getCurrentChar().dressing);
                        NegozioAbitiClient.Esci();
                    }
                };

            }
            BincoPant.Visible = true;
        }

Pant is a series of SubMenus created iterating the dressing List

TomGrobbe commented 5 years ago

You're adding a lot of submenus, each registers a new close event handler, of course all of them will be triggered, and only ONE submenu will be active. So the code will be executed for all of the submenu's that aren't opened. Meaning it'll be closed.

Instead, only register the onMenuClose event once (outside the foreach loop) and just keep a list of submenus outside that scope, and check if any of those submenus are open.

manups4e commented 5 years ago

oooooh i didn't think about that!! thank you 😅