ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   Lua/XML Help (https://www.esoui.com/forums/forumdisplay.php?f=175)
-   -   Show window when player opens inventory (https://www.esoui.com/forums/showthread.php?t=946)

Archer 04/16/14 07:44 AM

Show window when player opens inventory
 
i'm making an addon to show my stats, updated in real time, when i'm in my inventory screen. That way i can see my stats change when i equip armor, etc.

Screenshot: http://imgur.com/r0OsZ6p.png

However, i have no idea how to open and close that window when the player opens it's inventory. Right now the window is showed when I click on an invisible box in the lower left of my screen and hidden when i click again.

Is there a way to open it when the inventory opens and close it when the inventory closes?

Vicster0 04/16/14 07:58 AM

There are a few ways to acomplish this but what I see is most common is to register a function in your addon with the event manager to be ran when the action layer is pushed, then check that the inventory frame (or whicher you like) is show, and lastly show your control window. You can also do the same to hide the window when done using the action layer popped event.

Lua Code:
  1. EVENT_MANAGER:RegisterForEvent("youraddonpusheventname", EVENT_ACTION_LAYER_PUSHED, YourAddonPushFunction)
  2.  
  3. EVENT_MANAGER:RegisterForEvent("youraddonpusheventname", EVENT_ACTION_LAYER_POPPED, YourAddonPopFunction)

thelegendaryof 04/16/14 11:11 AM

Or you could attach it to the scene you'd like to attach it to directly:

Code:

local InventoryScene = SCENE_MANAGER.scenes.inventory
InventoryScene:RegisterCallback("StateChange", function(oldState, newState)
        -- states: hiding, showing, shown, hidden
        if(newState == "showing") then
                -- do something if the inventory is beginning to show
        elseif(newState == "hiding") then
                -- do something if the inventory is beginning to hide
        end
end)

That way it really only triggers when the inventory-scene changes (and not for any other scene)
and you're actually able to begin fading in your window on the exact same moment
it begins to fadein the inventory (or after it is done -> shown, hidden).

/zgoo SCENE_MANAGER.scenes
for a list of all scenes

Seerah 04/16/14 12:45 PM

Well, sure... If you want to do it the hard, complicated way. Or you can do it the easy-peasy lemon-squeezy way.

Set that inventory window as the parent to your addon's window. ;)

thelegendaryof 04/16/14 08:39 PM

Well if you prefer to attach it completely to the scene then correctly as a FadeSceneFragment. That way it autofades as well - thought a Scene can have different displaystates and sometimes you want to show your Window only in a specific case - if its hardlinked it will always show when that Scene is shown and there is no way to hide it yourself as it will always be faded in/out automatically in that case. To get the best of both worlds what I do in FastReport is add a virtual TopWindow that 's empty as a SceneFragment and use SetParent on it with my real Window. That way I can then check if my Addon triggered the Event and set it to hidden true/false in OnStateChange - and only in that specific case. Thought right now, Im not quite sure if it inherits the Alpha correctly (I'll check that out later).

Edit: F@cking WoT. Sorry I'm writing from my Phone right :)

Seerah 04/16/14 08:42 PM

Children inherit the alpha of their parent. If the animation makes the equipped inventory frame fade out, it's changing its alpha.

You can always add a toggle for your frame as well (if you really want to), as whether or not a frame is shown or hidden will be independent of its parent's visibility. Though, if they OP just wanted a toggle, they wouldn't have asked the question they did.

Vicster0 04/17/14 07:45 AM

Nice! As I said, I knew there were a few ways to accomplish this when I supplied the action layer hook but it's great to see the others in one place as well. I'm happy this thread exists, I will certainly be back to try some of these as I continue developing some things.

Great input from Seerah and thelegendaryof! Thanks guys! :)

Would be nice if we could start some threads on general topics like this, gather the many different ways to do things, and set some stickies! We could also transfer some of this info over to the Wiki which would be helpful. :banana:

thelegendaryof 04/17/14 07:51 AM

Quote:

Originally Posted by Seerah (Post 4685)
Children inherit the alpha of their parent. If the animation makes the equipped inventory frame fade out, it's changing its alpha.

You can always add a toggle for your frame as well (if you really want to), as whether or not a frame is shown or hidden will be independent of its parent's visibility. Though, if they OP just wanted a toggle, they wouldn't have asked the question they did.

Beware that the SceneManager uses SetHidden(true/false) on the Scenes Children as well not only Alpha. If I remember correctly that what why I was having difficulties even when I set InheritAlpha to false for my Window when attaching it directly via SetParent.

bsrealm 04/17/14 10:52 AM

I am trying to hide my UI when player is in any of the screens - inventory, character, mail, etc. I am using the pushed and popped events and checking for

Code:

if ZO_GameMenu_InGame:IsHidden() then
So I can keep it shown when in settings menu.

BUT, pushed is also called when I get into the mouse mode, where I need it to stay visible because I want the user to be able to move it. Any idea how I can detect pure mouse mode vs inventory et al is shown?

Thanks!

Total-Khaos 04/17/14 12:07 PM

Quote:

Originally Posted by bsrealm (Post 4752)
I am trying to hide my UI when player is in any of the screens - inventory, character, mail, etc. I am using the pushed and popped events and checking for

Code:

if ZO_GameMenu_InGame:IsHidden() then
So I can keep it shown when in settings menu.

BUT, pushed is also called when I get into the mouse mode, where I need it to stay visible because I want the user to be able to move it. Any idea how I can detect pure mouse mode vs inventory et al is shown?

Thanks!

This is how I accomplished what you're asking for:

Code:

function AutoHide()
        menu1 = ZO_GameMenu_InGame:IsHidden()
        menu2 = ZO_KeybindStripControlBackground:IsHidden()
        menu3 = ZO_InteractWindow:IsHidden()
        menu4 = ZO_Character:IsHidden()
        if not menu1 or not menu2 or not menu3 or not menu4
        then
                myAddonUI:SetMouseEnabled(false)
                myAddonUIBackdrop:SetHidden(true)
        else
                myAddonUI:SetMouseEnabled(true)
                myAddonUIBackdrop:SetHidden(false)
        end
end

Once this AutoHide function is called from your update function, it should show and hide your specified XML elements. In my example above, it disables the mouse and hides the backdrop I defined in my XML file and reverses that when the menus are closed.

EDIT: I'm not sure if this works with scene manager stuff, but you could change the code to show / hide depending on which menu system is currently opened.

bsrealm 04/17/14 12:33 PM

Perfect! Thanks good sir! Will confirm when I get home, saw your edit too.

Total-Khaos 04/17/14 02:58 PM

Quote:

Originally Posted by bsrealm (Post 4757)
Perfect! Thanks good sir! Will confirm when I get home, saw your edit too.

I've created a small example of this so you can see it in action. Here are the three files you need to create within a brand new "myAddon" folder in the same directory as your other addons.

Contents of the myAddon.txt file:

Code:

## Title: myAddon
## APIVersion: 100003

myAddon.lua
myAddon.xml

Contents of the myAddon.xml file:

Code:

<GuiXml>
        <Controls>
                <TopLevelControl name="myAddonUI" mouseEnabled="true" movable="true">
                        <Dimensions x="300" y="300" />
                        <Anchor point="CENTER" />
                        <OnUpdate>
                                myAddonUpdate()
                        </OnUpdate>
                        <Controls>
                                <Backdrop name="$(parent)Backdrop" inherits="ZO_DefaultBackdrop" alpha="1.0" />
                                <Label name="$(parent)Label" font="ZoFontGame" color="FFFFFF" alpha="1.0">
                                        <Anchor point="TOP" />
                                </Label>
                        </Controls>
                </TopLevelControl>
        </Controls>
</GuiXml>

Contents of the myAddon.lua file:

Code:

function myAddonUpdate()
        AutoHide()
        myAddonUILabel:SetText(string.format("This is a test label"))
end

function AutoHide()
        menu1 = ZO_GameMenu_InGame:IsHidden()
        menu2 = ZO_KeybindStripControlBackground:IsHidden()
        menu3 = ZO_InteractWindow:IsHidden()
        menu4 = ZO_Character:IsHidden()
        if not menu1 or not menu2 or not menu3 or not menu4
        then
                myAddonUI:SetMouseEnabled(false)
                myAddonUIBackdrop:SetHidden(true)
                myAddonUILabel:SetHidden(true)
        else
                myAddonUI:SetMouseEnabled(true)
                myAddonUIBackdrop:SetHidden(false)
                myAddonUILabel:SetHidden(false)
        end
end

Let me know if you can't get this working and I'll see what I can do to help. Thanks!

EDIT: Please note that there might be an even easier way to do this, but I didn't spend a whole lot of time researching. :)

Seerah 04/17/14 04:02 PM

  1. Always use events instead of an OnUpdate script if events are available.

  2. If you must use an OnUpdate script, then buffer that OnUpdate script so that it's not called on each and every frame draw (if you have 50fps, that's 50 times per second your function is trying to run).

  3. Always make your variables/functions/etc. local unless you must have them in the global scope. If they have to be global, then give them unique names. AutoHide, menu1, etc. are not unique. If another developer slips and leaks a variable named menu1 into the global scope, the two variables will overwrite one another. Keeping them local avoids this problem, and is better for performance.

  4. Don't use string.format if you're not actually doing any formatting. Just use :SetText("text"). It'll save you a function call.

  5. The backdrop and label are children of your myAddonUI control. As I explained earlier in this thread, they will inherit visibility from their parent. Don't call :SetHidden() for these. Just call :SetHidden() on the parent frame. And then you can leave the :SetMouseEnabled() call out of it. Because it'll be hidden. This will save you two function calls here.

Total-Khaos 04/17/14 08:07 PM

Quote:

Originally Posted by Seerah (Post 4771)
  1. Always use events instead of an OnUpdate script if events are available.

  2. If you must use an OnUpdate script, then buffer that OnUpdate script so that it's not called on each and every frame draw (if you have 50fps, that's 50 times per second your function is trying to run).

  3. Always make your variables/functions/etc. local unless you must have them in the global scope. If they have to be global, then give them unique names. AutoHide, menu1, etc. are not unique. If another developer slips and leaks a variable named menu1 into the global scope, the two variables will overwrite one another. Keeping them local avoids this problem, and is better for performance.

  4. Don't use string.format if you're not actually doing any formatting. Just use :SetText("text"). It'll save you a function call.

  5. The backdrop and label are children of your myAddonUI control. As I explained earlier in this thread, they will inherit visibility from their parent. Don't call :SetHidden() for these. Just call :SetHidden() on the parent frame. And then you can leave the :SetMouseEnabled() call out of it. Because it'll be hidden. This will save you two function calls here.

I'm just learning myself; however, I noticed that if I just set my parent to hidden, it doesn't reappear when it should. I hit ESC to open the game menu for example, the parent hides as expected, but never reappears when the ESC game menu is closed.

Code:

        if not menu1 or not menu2 or not menu3 or not menu4
        then
                myAddonUI:SetHidden(true)
        else
                myAddonUI:SetHidden(false)
        end

This is why I opted to hide all the children instead.

Seerah 04/17/14 08:43 PM

If your frame isn't being reshown when it you want it to be, then something isn't quite right with your code. :)

Total-Khaos 04/18/14 07:33 AM

Quote:

Originally Posted by Seerah (Post 4797)
If your frame isn't being reshown when it you want it to be, then something isn't quite right with your code. :)

Haha, exactly. Oh well, I'll look into the whole buffer / events stuff to see if I can make this "smarter" for lack of a better term.


All times are GMT -6. The time now is 09:37 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI