ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   Lua/XML Help (https://www.esoui.com/forums/forumdisplay.php?f=175)
-   -   Add guild/friend lists context menu item (https://www.esoui.com/forums/showthread.php?t=10474)

sinnereso 03/09/23 11:48 PM

Add guild/friend lists context menu item
 
Im considering adding a context menu item to the guilds, friends and group lists.. possibly chat as well for saving someone to a saved variable for use in my addon.

Im trying to keep this light and wanting to avoid mouse click events etc but might have no choice. Also im trying to avoid dependencies if possible.

Is there a quick, easy and clean non-intrusive way to achieve this without utilizing libcustommenu? Literally just to save that persons @NAME to a saved variable? I have read Beartrams warning regarding not using it or doing this improperly which is why im here poking around :)

Baertram 03/10/23 04:06 AM

Why don't you just use LibCustomMenu as it integrates and was build EXACTLY for that purpose? :confused:
Other addons using the same lib are compatible on the fly and you do not destroy other addons by making your own hacks and workarounds.

Do what you like but those libs exist for a reason and often also provide the easiest way achieving the goal.

Add it as an optional dependency and tell the guys that your addon's feature with the context menu only works if the lib is installed.
Do an

Lua Code:
  1. if not LibCustomMenu then return end

check at the start of your function that adds the context menu and all is done.
Users can use your adodn w/o dependecy then and only need it for the context menu features.

sinnereso 03/10/23 04:17 AM

Hmm.. ok u sold me on it. Its actually for a feature already done another way, this is just for convenience. I'll look into the lib then

sinnereso 03/10/23 04:53 AM

ok ive begun integrating it..
ive added to my manifest:

## OptionalDependsOn: LibCustomMenu>=680 <<< ive found this in another addon but no idea what the number means... line#?

and just starting throwing a function together with stuff till it makes sense to me :)

Code:

function MyAddon.SaveContext()
        if not LibCustomMenu then return end
        AddCustomMenuItem("Save to MyAddon", MyAddon.SavePlayer())
        --or
        lib:RegisterGuildRosterContextMenu(MyAddon.SavePlayer(), lib.CATEGORY_LATE, ...)
        return
end

i realize this is nowhere close to working as i haven't told it which menu and what to save.

Baertram 03/10/23 06:32 AM

Quote:

Originally Posted by sinnereso (Post 47336)
## OptionalDependsOn: LibCustomMenu>=680 <<< ive found this in another addon but no idea what the number means... line#?

Check the WIKI for such questions, it explains what the manifes txt file contains and why there are such things like >= version etc. for libraries
https://wiki.esoui.com/Addon_manifest_(.txt)_format
-> https://wiki.esoui.com/Addon_manifes...rmat#DependsOn

https://wiki.esoui.com/Libraries#.23...ned_integer.3E

And about LibCustomMenu:
The description provides examples how to add such contextmenus.

Guild roster - Just add 1 call at e.g. your EVENT_ADD_ON_LOADED.

Lua Code:
  1. if LibCustomMenu ~= nil then
  2.    local function func(rowData)
  3.     ---rowData contains the row's data table of the right clicked guild roster row
  4.     --so get whatever you need from rowData
  5.     --You coudl add rowData to your global variable MyAddon._rowData and the inspect MyAddon._rowData with merTorchbug or zgoo ingame to see what it provides. I think there is a displayName in the rowData and maybe the charatcterName, a memberIndex of that row, etc.
  6.        MyAddon.SavePlayer(rowData.displayName) --only an example, dunno if displayName exists in there
  7.    end
  8.    --category can be any of the categories of the lib do define if teh contetx menu entyr should be added early (at the top of the context menu -> don't do that as all vanilla contetx menu entries should stay there so users do not get confused...) or at the bottom of the context menu.
  9. --[[
  10. category
  11. lib.CATEGORY_EARLY
  12. lib.CATEGORY_PRIMARY
  13. lib.CATEGORY_SECONDARY
  14. lib.CATEGORY_TERTIARY
  15. lib.CATEGORY_QUATERNARY
  16. lib.CATEGORY_LATE
  17. ]]
  18.  
  19.    local category = LibCustomMenu.CATEGORY_LATE
  20.    LibCustomMenu:RegisterGuildRosterContextMenu(myFunc, category)
  21. end
  22.  
  23. For the other context menu at the chat etc. check the description, it works about the same like teh guidl roster.
  24. 1 function needs to be registered which is called as the chat entry is right clicked and you define the callback function of your addon and the category etc.

sinnereso 03/10/23 06:57 AM

thank you... ive been searching for the manifest number and where might be best to call this.. been peeking around a few addons for it too but so far been too complex to understand.

I'll give some of this this a whirl.

sinnereso 03/10/23 08:28 AM

Based on your example ive got this in addon loaded and appears to work with the category setting which i assumed wasnt nessisary if it was the default setting. This code does progress to the "MyAddon.SavePlayerContext" function and run it. I guess what I dont fully understand now is am I to "addcustommeenuitem" etc myself now? What exactly is "libcustommenu" doing that I dont have to if it so super easy?

Code:

if LibCustomMenu ~= nil then
        local function func(rowData)
                  MyAddon.SavePlayerContext(rowData.displayName)
        end
        local category = LibCustomMenu.CATEGORY_LATE
        LibCustomMenu:RegisterGuildRosterContextMenu(MyAddon.SavePlayerContext, category)
end

seems more confusing not less to me.. im new at this so i like or even need to follow everystep

Baertram 03/10/23 03:03 PM

The library provides you the "entry" (a hook into vanilla code), via acallback function with fixed parameter (rowData) which is fired as the context menu is build by vanilla code.
You "Register" your callback function, just like you register your callback for an event or register a callback for a CALLBACK_MANAGER:FireCallbacks(.. function trigger.
And then this function is executed as the vanilla code runs, and assists you with compatibility for addons, and vanilla code, and an easy way to add your own entries to the context menu.

So yes, inside your callback you need to add a custom menu entyr IF this is your goal in the end.
The callback function func(rowData) should be usedto do so and you have the benefit of already knowing rowData and it's values so you could add teh contexmenu entry based on that rowData information, e.g.

Code:

if rowData.displayName and rowData.displayName == GetDisplayName() then do something for your own user else do something for another user end

Attention: Do not call ClearMenu() inside that callback as else it will clear the total ZO_Menu and all vanilla and other addon context meneu entries will be gone!

sinnereso 03/10/23 03:16 PM

Well Ive never used a callback and trying to understand what that even is still but ive made progress.. with this ive got the menu item then when clicked drops an error stating it was expecting a function instead of nil..

I have this nagging feeling the AddMenuContext function should up up in the ONLOAD part tbh.

What you see below particularly the last function thats mostly comented out is more or less all I want it to do.

Code:

ONLOAD()
if LibCustomMenu ~= nil then
                local function func(rowData)
                      MyAddon.AddMenuContext(rowData.playerName)
                end
                local category = LibCustomMenu.CATEGORY_LATE
                LibCustomMenu:RegisterGuildRosterContextMenu(MyAddon.AddMenuContext, category)
        end

function MyAddon.AddMenuContext(playerName) <<<<<< this is adding the menu item but error clicking in guild menu
        AddCustomMenuItem("MyAddon Save",  MyAddon.SavePlayerContext(playerName))
end

function MyAddon.SavePlayerContext(playerName) <<<<<<<<<its not liking this section at all yet
        --local playerToBeSaved = playerName
        --MyAddon.savedVariables.savedPlayer = playerToBeSaved
        --df("|c6666FF[MyAddon]|r Saving: %s", playerToBeSaved)
end


Baertram 03/10/23 04:16 PM

Quote:

Well Ive never used a callback
And how did you let your addon properly load then if you never did use a callback so far? :D
Every EVENT_MANAGER:RegisterFor is using a callbackFunction that is called as the event fires, e.g. the OnAddonLoaded function you have defined for your EVENT_ADD_ON_LOADED (hopefully).

You cannot do such:
Lua Code:
  1. AddCustomMenuItem("MyAddon Save",  MyAddon.SavePlayerContext(playerName))
  2. end

AddCustomMenuItem got a dedicated signature, which means you need to pass in a function as the 2nd parameter and not a result of a function, which is what would be passed in if you "call" your function MyAddon.SavePlayerContext(playerName) there!
You need to add it with a closure around it so it does not get called as you pass it in the parameter, but get's called as it's own function as the 2nd param is needed:

Lua Code:
  1. AddCustomMenuItem("MyAddon Save",  function() MyAddon.SavePlayerContext(playerName) end)

This function() yourFunctionNameWithParam(param1, param2) end is doing the following:
It will pass in a function (an anonymous one without name) and as this function is called at any time within LibCustomMenu code, the internal function MyAddon.SavePlayerContext(playerName) will be called, at that time (as the context emnu entry is clicked).

Else you'd just pass in the return value of MyAddon.SavePlayerContext(playerName), at the point the AddCustomMenuItem("MyAddon Save", MyAddon.SavePlayerContext(playerName)) was read from the code interpreter (means as the code is read the first time which would be way too early even before the contex menu was opened)!

And if that is nil as your function MyAddon.SavePlayerContext(playerName)) does not return anything, this is why you get the nil error but function expected !
If would work again if your function MyAddon.SavePlayerContext(playerName) would return a function e.g. return function() doSomething(playerName) end.

sinnereso 03/10/23 04:36 PM

Thank you. This stuff is way over my head but is last useful function and all our pain is over :) Well not entirely.. need todo this for guild list, friends list, group list and possibly chat.

Heres what i got so far but i need a break I cant even think anymore. I need to find a way to get the players @name down to the bottom function so it can be saved to the variable.

Code:

ONLOAD()
if LibCustomMenu ~= nil then
                local function func(rowData)
                        MyAddon.AddMenuContext(rowData.displayName)
                end
                local category = LibCustomMenu.CATEGORY_LATE
                LibCustomMenu:RegisterGuildRosterContextMenu(MyAddon.AddMenuContext, category)
end

function MyAddon.AddMenuContext()
        AddCustomMenuItem("MyAddon Save",  function() MyAddon.SavePlayerContext(rowData.displayName) end)
end

function MyAddon.SavePlayerContext()
        --local playerToBeSaved = rowData.displayName
        df("|c6666FF[MyAddon]|r Saving: %s", rowData.displayName)
end


Baertram 03/10/23 04:40 PM

https://www.lua.org/pil/6.html

Maybe that will explain it (anonymous functions e.g.) with more details

sinnereso 03/10/23 07:55 PM

ok ive been reading that and some useful stuff in there but going slow. For the moment I've sidetracked a bit to working on the friendslist and chat functionality and managed to get chat working too as its very similar.

By working i mean i can chat output my own username or text or something locally to the function no problem but I'm still unable to get the playerName data from the rowdata down to the function.

also.. is there a similar friendslist function in libcustommenu??? I dont see any mention of it in the addon description or inside the library itself ive scanned all through it.

sinnereso 03/11/23 04:37 AM

the chat context seems to be working perfectly but nomatter what I do i still get "table:000023908713BHS&HS" or similar from the rowdata for the guild context.

Also ive been digging for hours and there 0 info for friends list and group list context menus? are guild and chat my only options?

Im trying to convert everything into an @NAME in "playerName" so i can use 1 function to save to variable & display it in chat that its doing that.

Code:

if LibCustomMenu ~= nil then
                local function func(rowData)
                        MyAddon.AddMenuContext(rowdata.displayName)
                end
                local function func(playerName, rawName)
                        MyAddon.AddMenuContext(playerName, rawName)
                end
                local category = LibCustomMenu.CATEGORY_LATE
                LibCustomMenu:RegisterGuildRosterContextMenu(MyAddon.AddMenuContext, category)
                LibCustomMenu:RegisterPlayerContextMenu(MyAddon.AddMenuContext, category)
end


Baertram 03/11/23 05:43 AM

if you get something like table:000023908713BHS&HS then it means your are passing in the total table and not 1 value of that table, e.g. you pass in rowData and not rowData.subVariableInThatTable.

As I said, add the rowDate in your callback function to your global addon table like

myAddon._rowdata = rowdata

Then use an addon like merTorchbug or zgoo and inspect your global variable myAddon
via slash command /tb myAddon
or /zgoo myAddon

You will see all values of that table (myAddon) that way and can click on the _rowData subtable to see what it contains.
In there you might find something like characterName or memberIndex or similar whch was provided by the callback function of the guildRoster context menu and that way you can use the memberIndex or something that was provided in that rowData table to use for your usecase, like get the name of the clicked row etc.


And you also need to pay attention if the signaure of the callback functions you pass in to RegisterGuildRosterContextMenu and RegisterPlayerContextMenu (I meant the first parameter, your callback function "MyAddon.AddMenuContext") is the same, if it uses the same parameters. Maybe 1 got rowData of the guildMember you right clicked on and the other one got no rowData table but just a string with the chat name you clicked on?
Check it inside the LibCustomMenu.lua file, where the RegisterGuildRosterContextMenu and RegisterGuildRosterContextMenu functions are called OR at the description of the addon!


About friendsList I'm not sure if LibCustomMenu provides that already or not. if the description lacks that info I doubt it's in there until now and must be added. But maybe it's in the code of the lib already, so check the lua file of LibCustomMenu for "friend" or similar, and maybe you can find the API function to register a context menu that way.
Edit: I briefly scanned the code and it does not look like it supports the friendslist until now.
Maybe raise a request at the addon comments of LibCustomMenu for that:
lib:RegisterFriendsListContextMenu(func, category, ...)

sinnereso 03/11/23 06:06 AM

Thank you again.. ive tried mertorchbug and had trouble even making sense of how to use it. Ill give em another go but the chat context is working perfectly and saving at this moment at least... I got SOME satisfaction :)

I might try zgoo this time to see if its more userfriendly for me

Baertram 03/12/23 03:58 AM

MerTorchbug UI is more user friendly than zgoo imo, but that's up to you in the end.
Both inspect vatisbles so that you see the values. For example if you define a global variable table MyAddon = {} you can inspect it via /tb MyAddon or /zgoo MyAddon (type to the chat editbox just like you would run a /script).

The ui will show you the table then and all of its content. You can click tables in that table, or see the variables. If the insoected variable is a control you can see its values like height width anchor hidden etc.
This way you can see values of variables instead of having to write them to the chat via d() debug messages.

If you use /tb alone you'll see the global inspector showing you all kind of tabs like loaded addons, loaded libraries, String constants SI_* which can be used with the GetString function, constsnts in the game like BAG_BACKPACK and its value, global classes like ZO_Smithing and its created object SMITHING, fonts and so on.

All those global variables are stored inside one global table _G in lua. So basically all is stored in tables in lua and with merTorchbug or zgoo you can insprct this tables at runtime.

sinnereso 03/12/23 05:23 AM

Ya both seem informative but i kept getting stuck with blank windows open with torchbug... zgoo feels better for me so far.

Also got it all fixed up now.. "rowData" was actually "data". I picked up on this after votan upgraded LibCustomMenu after i requested it to include group and friends list.. his additional descriptions made it all suddenly clear.

Thank you for all your help.

Baertram 03/12/23 06:07 AM

You need to use merTorchbug updated! The original one is outdated and not functioning.
If your window that opens is blank try to resize it, sometimes the size is too small to show the info.
Or if it's blank your inspected table is maybe empty and just shows as blank window.

sinnereso 03/26/23 04:19 PM

I messed up my save player function somehow this morning cleaning up notes and many unessissary variables or so I thought.

The saved variable is saving correctly.. the DF output is outputting correctly and yet Im getting a nil value error on editing the text field in the setting panel just below it.

Heres what i got setup atm and shud only be a local variable to fix it I would think. Any suggestions would be appreciated. I was soo close to done with this thing.

Code:

--ADDON LOADED--
local category = LibCustomMenu.CATEGORY_LATE--<<< context menu stuff
LibCustomMenu:RegisterGuildRosterContextMenu(MyAddon.AddGGFContext, category)
LibCustomMenu:RegisterFriendsListContextMenu(MyAddon.AddGGFContext, category)
LibCustomMenu:RegisterGroupListContextMenu(MyAddon.AddGGFContext, category)
MyAddon:CreateSettingsWindow()

-- LibAddonMenu SETTINGS PANEL TEXT FIELD --
{
                type = "description",
                text = "Saved Player:  " .. tostring(MyAddon.savedVariables.savedPlayer),
                reference = "MyAddon_SETTINGS_SAVEDPLAYER_TEXT",
                width = "half",
},

------ Save player functions ------
241-function MyAddon.AddGGFContext(data)
242->        AddCustomMenuItem("Save to MyAddon", function() MyAddon.SavePlayer(data.displayName) end)
243-end

245-function MyAddon.SavePlayer(displayName)
246        MyAddon.savedVariables.savedPlayer = displayName
247        df("|c6666FF[MyAddon]|r Saving: " .. tostring(displayName))-- WORKING FINE
248->        MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data.text = "Saved Player: " .. tostring(displayName)-- ERRORS APPEAR TO BE HERE AND BELOW REPORTING NIL VALUE FOR IM ASSUMING "displayName"
249-        MyAddon_SETTINGS_SAVEDPLAYER_TEXT:UpdateValue()
250-end

ERRORS:
Code:

user:/AddOns/MyAddon/MyAddon.lua:248: attempt to index a nil value
stack traceback:
user:/AddOns/MyAddon/MyAddon.lua:248: in function 'MyAddon.SavePlayer'
user:/AddOns/MyAddon/MyAddon.lua:242: in function 'OnSelect'
/EsoUI/Libraries/ZO_ContextMenus/ZO_ContextMenus.lua:476: in function 'ZO_Menu_ClickItem'
user:/AddOns/LibCustomMenu/LibCustomMenu.lua:604: in function 'MouseUp'


Baertram 03/26/23 04:49 PM

Seriously, you should please follow the rules like all others too.
If you get any error message:

1. Post the whole error message so we can see the error message AND the line numbers AND the exapanded variables from the error mesasge
2. Post your code or at least the code block around the lines of the error message WITH line numbers or at least the line number where the error message hits

We cannot assume things nor do we like to and I personally often do not understand what you talk about in your posted code lines (what should "on editing the text field in the setting panel just below it." relate to in your posted code :confused:)

Many thanks for easing it for us all.

I also posted you the "how to read lua error messages" before already so maybe read the info there and learn to read the error messages, or ask questions about the error mesasges in detail so we can explain it to you better. You often, especially for nil errors, find out what's up if you understand the error messages and learn them, instead of ignoring them :p They tell you what is missing by the error text like "try to index a nil value" -> you got a table which is nil and try to access it somehow before it was created properly with = {}, etc.

sinnereso 03/26/23 05:01 PM

Quote:

Originally Posted by Baertram (Post 47466)
Seriously, you should please follow the rules like all others too.
If you get any error message:

1. Post the whole error message so we can see the error message AND the line numbers AND the exapanded variables from the error mesasge
2. Post your code or at least the code block around the lines of the error message WITH line numbers or at least the line number where the error message hits

We cannot assume things nor do we like to and I personally often do not understand what you alk about in your poasted code lines (what should "on editing the text field in the setting panel just below it." relate to in your posted code :confused:)

Many thanks for easing it for us all.

I also posted yuteh "how to read lua error messages" before already so maybe read the info there and learn to read the error messages, or ask questions about the error mesasges in detail so we can explain it to you better. You often, especially for nil errors, find out what's up if you understand the error messages and learn them, instead of ignoring them :p They tell you what is missing by the error text like "try to index a nil value" -> you got a table which is nil and try to access it somehow before it was created properly with = {}, etc.

OK relax I'll do my best to provide.. Is there maybe a better place to ask addon questions? You tell me you dont like to or have time to answer personal messages and then jump on my forum posts as if they were directed to you personally. Exuse me I'm not a professional and doin my best!

ERRORS: ill add to bottom of my post as well so they close and handy for all to see and add the codes lines!
Code:

user:/AddOns/MyAddon/MyAddon.lua:248: attempt to index a nil value
stack traceback:
user:/AddOns/MyAddon/MyAddon.lua:248: in function 'MyAddon.SavePlayer'
user:/AddOns/MyAddon/MyAddon.lua:242: in function 'OnSelect'
/EsoUI/Libraries/ZO_ContextMenus/ZO_ContextMenus.lua:476: in function 'ZO_Menu_ClickItem'
user:/AddOns/LibCustomMenu/LibCustomMenu.lua:604: in function 'MouseUp'


Baertram 03/26/23 08:30 PM

Quote:

You tell me you dont like to or have time to answer personal messages and then jump on my forum posts as if they were directed to you personally
I do not need to relax, I'm already fully relaxed.
And yes: I do not need to answer each PM if the info is valuable for others too, that's what forums are made for.
I also provided you the link to the addon devs gitter chat where you could ask the same questions and addon/lua/xml related things, but you do not want to post there, so the forums here are okay.

But if you post here the same rules apply to you as to anyone else: Read before write please!
-> I'm a forum mod, that's why I "jump on your post" (and any others around here!) and I'm just telling you the same as I do write to any other here :rolleyes:

Especially if we/I had linked you the ressources already where there is written how to read the lua error messages.
Here you go once again:
https://www.esoui.com/forums/showthread.php?t=8858
-> "lua error messages ingame - How do I read them?"

And how errors should be posted to all of us (not me in particular) so we can understand and help more easily and effectively:
https://www.esoui.com/forums/showthread.php?t=8858
-> "How to report a lua error message/a bug to the developers"


I also adviced you, in case you do not understand the written information/explanation there, to feel free to name us and ask about what you do not understand, and we might be able to help you understand it (better).
This got nothing to do with being a professional developer (neither am I) or not, that's communication and if you are willing to learn we are willing to help.


As an exaplanation: The error says
user:/AddOns/MyAddon/MyAddon.lua:248: attempt to index a nil value

So the error happens in file MyAddon/MyAddon.lua line 248
As I wrote before it's about "index a nil value" -> means there is a variable in that line which should be a table, but it does not exist.

Your line 248 is:
MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data.text = "Saved Player: " .. tostring(displayName)-- ERRORS APPEAR TO BE HERE AND BELOW REPORTING NIL VALUE FOR IM ASSUMING "displayName"

So what is a table in this line?
MyAddon_SETTINGS_SAVEDPLAYER_TEXT for example is
Or MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data is too
Any of these seems to be nil at the point where the error happens.

So either MyAddon_SETTINGS_SAVEDPLAYER_TEXT or MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data does not exist.
Add some d(tostring(MyAddon_SETTINGS_SAVEDPLAYER_TEXT)) or d(tostring(MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data)) to see which one is nil.
And then work yor way back from the error (the error message shows you the "call stack -> from bottom to top where the error occurs) to the start and check where your variables MyAddon_SETTINGS_SAVEDPLAYER_TEXT and MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data are properly created and filled.

Keep in mind that lua does not know local defined variables if they are defined after the calling code, or inside any if .. end, for .. do, or other closure, and you want to use the same variable otuside of the closure!
Either define MyAddon_SETTINGS_SAVEDPLAYER_TEXT at the top of your addon file MyAddon.lua, as a local.
And also define MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data there as {} empty tbale directly.
Or at least once before it is tried to be accessed in line 248 finally.


btw: Looks like MyAddon_SETTINGS_SAVEDPLAYER_TEXT is a LibAddonMenu control you wan to create for your settings panel?
It's not accessible before the addon panel was loaded!!!
Before it's simply nil.

LibAddonMenu provides a callback that fires as the panel get's loaded, and as the controls were created. So you could use that to see if the control was created:
https://www.esoui.com/downloads/info7-LibAddonMenu.html
-> WIKI about callbacks: https://github.com/sirinsidiator/ESO...LAM2-callbacks

But basically you do not need to manually update MyAddon_SETTINGS_SAVEDPLAYER_TEXT if it got a getFunc. Just let it read the actual value from your SavedVariables there.
But as the control is a description it got no getFunc so you need to manually update it.
-> Thus you need to use LibAddonMenu's callback for PanelControlsCreated to update it for the first time, as your panel was loaded and all controls were build properly.
Be carefull with that callback functions, as it will run for EACH addon once! So you must check the panel loaded is yours as described or it will run too often.

Lua Code:
  1. CALLBACK_MANAGER:RegisterCallback("LAM-PanelControlsCreated", function(panel)
  2.     if panel ~= myPanel then return end
  3.     -- do something
  4. end)

myPanel is the variable that your addon settings panel returns as you create it via function LibAddonMenu2:RegisterAddonPanel(yourPanelName, yourPanelData) !

In order to let the callbacks work properly you night need to add the registerForRefresh at yourPanelData table! Check the Wiki documentation if this is needed for the LAM-PanelControlsCreated calback please.


And in your function where you try to access MyAddon_SETTINGS_SAVEDPLAYER_TEXT you need to check if it's nil or not!

Lua Code:
  1. if MyAddon_SETTINGS_SAVEDPLAYER_TEXT ~= nil then
  2.  ---update it
  3. end

sinnereso 03/26/23 09:45 PM

ty for all of that. I will try to make use of it but it appears none of them solve my solution. If MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data.text doesn't exist yet until the addon options are opened, and CALLBACK_MANAGER:RegisterCallback("LAM-PanelControlsCreated", function(panel) as per its description fires only after all controls are created after its opened then even it wont help me.

What im apparenrly needing is all controls created and existing upon load/reload. Im really not sure how I never noticed this before or if its related to the recent libcustommenu update but this is big problem for me. Its a primary function and having to open addon settings 1st doesn't work for me =p

sinnereso 03/26/23 10:04 PM

MyAddon_SETTINGS_SAVEDPLAYER_TEXT is the reference to the control in my settings menu.

The function having the error is attempting to edit the text on it but apparently cant until the user goes into the addon settings 1st because it doesn't exist yet.

is there a way to make the addon settings and controls exist when the addon loads?

Baertram 03/27/23 07:14 AM

No.

Why do dou even need your addon to use that control,it only shows in the settings panel? So why should it update before one opens this?
As I said you could add a nil check in your function so it does not try to update that description control at the settings if it does not exist yet.
That way your function still runs even without having the addon settings opened once. And with the Lam Panel Controls Created callback you can update it as someone opens the settings.

sinnereso 03/27/23 07:28 AM

Quote:

Originally Posted by Baertram (Post 47471)
No.

Why do dou even need your addon to use that control,it only shows in the settings panel? So why should it update before one opens this?
As I said you could add a nil check in your function so it does not try to update that description control at the settings if it does not exist yet.
That way your function still runs even without having the addon settings opened once. And with the Lam Panel Controls Created callback you can update it as someone opens the settings.

I need it to do this because its informational for the user to know WHO they have saved to port to and mount etc. If they cant remember they can open the settings and see.

im going to try the callback and detect if it exists already or not maybe.. if it doesn't exist yet then just save the variable and be done with it... It might work like this.

Baertram 03/27/23 08:03 AM

It cannot work by any other way ;)

If settings were not opened the control is nil, so just save without updating the control. As noone opened the settings noone will see the label or tries to see the label, so there is no reason to update it !
If the settings were opened, use the controls created calback, check for YOUR addon's panel and then update the description text of the label.
If it does not dautomatically update by changing the conrol.data.title or control.data.text value, try to change the control.data.title or .text attributes and then call control:UpdateValue() function, it should update the label's text then based on the data table.

sinnereso 03/27/23 08:48 AM

Quote:

Originally Posted by Baertram (Post 47473)
It cannot work by any other way ;)

If settings were not opened the control is nil, so just save without updating the control. As noone opened the settings noone will see the label or tries to see the label, so there is no reason to update it !
If the settings were opened, use the controls created calback, check for YOUR addon's panel and then update the description text of the label.
If it does not dautomatically update by changing the conrol.data.title or control.data.text value, try to change the control.data.title or .text attributes and then call control:UpdateValue() function, it should update the label's text then based on the data table.


I would be happy doing that except the settings panel IS getting its data ON_LOAD and storing it someplace during the MyAddon:CreateSettingsWindow(). So whats happening is user logs in and plays etc, then right clicks someone to "Save players @NAME" for my addon use which works fine except the settings panel still shows the OLD @NAME when you open the addon settings. SO it IS getting the data and storing it someplace and then creating the controls with it later when you open the addon settings. I need to find where that place is and edit that when the control data is NIL.

I currently have a temporary fix for people with your idea of detectinf if the data is nil so it just skips it.. addon works fine but cosmetically the settings panel will always show the previous @NAME the 1st time they open addon settings. Infact will always show the previous one until they have opened the addon settings so I can then edit the field properly.

Baertram 03/27/23 12:20 PM

I have partially described how to fix that settings panel showing the old value above already, using LibAddonMenu's callback for LAM-PanelControlsCreated.

And if you had looked at the LibAddonMenu WIKI pages I linked above you would have seen there is another callback LAM-PanelOpened, which you could use in to update the label each time your LAM panel opens (Add a nil chck in there as the 1st time it's called maybe before LAM-PanelControlsCreated!).

Both in combination should fix your issues.

sinnereso 03/27/23 01:27 PM

*EDIT*

I got it figured out.. I used the reference for the description field to detect the right addon settings are selected and when its created. Did the job.

Baertram 03/27/23 07:57 PM

But my post above explains how to detect it's YOUR addon panel that was created, or opened...
>myPanel is the variable that your addon settings panel returns as you create it via function LibAddonMenu2:RegisterAddonPanel(yourPanelName, yourPanelData) !
---> local myPanel
--- do addon options etc and add it to yourPanelData
---- ... addon controls here
---myPanel = LibAddonMenu2:RegisterAddonPanel(yourPanelName, yourPanelData)
--in the callback functions check for the parameter panel of the callbacks == myPanel or else return

All you need to do now is use the 2 callbacks, "controls created" and "panel opened", check for your panel or else return (as it's another panel then) and then update your descriptions data and use UpdateValue to force the update on it.

I had prepared all that for you already, you just need to take the time and read it, read the Wiki, and try to understand it. If you do not understand it, ask as adviced, instead of reinventing the wheel (which sometimes makes sense for a learning effect but will result in errors in longterm).

sinnereso 03/27/23 11:17 PM

I do thank you very much for all your help. Its very difficult for me to know when what you type is directly the answer or random hypothetical and for me to research for days. I did spend the day on it and came up with this below because i had troule making sense of the panel and myPanel data.

Code:

------ Save player ------
function MyAddon.AddGGFContext(data)
        AddCustomMenuItem("Save to MyAddon", function() MyAddon.SavePlayer(data.displayName) end)
        return
end

function MyAddon.SavePlayer(displayName)
        MyAddon.savedVariables.savedPlayer = displayName
        df("|c6666FF[MyAddon]|r Saving: " .. tostring(displayName))
        if MyAddon_SETTINGS_SAVEDPLAYER_TEXT == nil then--<<< Checking if settings panel has been created
                CALLBACK_MANAGER:RegisterCallback("LAM-PanelControlsCreated", function(panel)
                        if MyAddon_SETTINGS_SAVEDPLAYER_TEXT == nil then--<<< Checking if settings panel has been selected
                                return
                        else
                                MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data.text = "Saved Player: " .. tostring(displayName)
                                MyAddon_SETTINGS_SAVEDPLAYER_TEXT:UpdateValue()
                                return
                        end
                end)
                return
        else
                MyAddon_SETTINGS_SAVEDPLAYER_TEXT.data.text = "Saved Player: " .. tostring(displayName)
                MyAddon_SETTINGS_SAVEDPLAYER_TEXT:UpdateValue()
                return
        end
end

this checks the actual description control that im editing in the panel. if it doesnt exist when user saves someone via context menu it saves the variable and registers the callback so when they open addon settings it updates the description field then.

if it does exist then it just saves variable and edits the description field as normal.

I couldnt find a reference that made sense to me for the panel but did have one for the description field so this worked perfectly i think.

What I have seems to work perfectly and is the last bug I can find so im gonna pump it out to the masses but.. i will research this more and look at your suggestion till im blue in the face and see if i can make it work soon.

Baertram 03/28/23 04:21 AM

The callback for lam needs to be registered once! In you addons settings code. Not each time in your "SavePlayer" function.

Having it the way you use it now will make the else... execute for each addon, not only yours! If you use 30 addons with settings (or anyone else using your addon does) it will run the panel callback code 30 times for nuts!

Just move the callback code to the lam creation and use the panel parameter of the callback to check if it is your panel as described above in my last post (you get the panel to compare from your lam registerAddonPanel function! After that create the callback for controlsCreated once, and also create the callback for panelOpened to update your description. This will update the description label each time your settings panel opens, so using your player saved function does not need to update that label, unless you use it while the settings panel is actually opened? Then just check if the control is not nil and update directly ).

Baertram 03/28/23 07:48 AM

1 Attachment(s)
Here is your RidinDirty.lua file with my changes, hope you understand it better that way seeing the code.
If you got questions, ask ;)

It's untested so please test if it works as expected.

sinnereso 03/28/23 08:58 AM

Quote:

Originally Posted by Baertram (Post 47479)
The callback for lam needs to be registered once! In you addons settings code. Not each time in your "SavePlayer" function.

Having it the way you use it now will make the else... execute for each addon, not only yours! If you use 30 addons with settings (or anyone else using your addon does) it will run the panel callback code 30 times for nuts!

Just move the callback code to the lam creation and use the panel parameter of the callback to check if it is your panel as described above in my last post (you get the panel to compare from your lam registerAddonPanel function! After that create the callback for controlsCreated once, and also create the callback for panelOpened to update your description. This will update the description label each time your settings panel opens, so using your player saved function does not need to update that label, unless you use it while the settings panel is actually opened? Then just check if the control is not nil and update directly ).

OH WOW! ty.. ill take a look at it right now. And yes the label doesn't need to be changed while in the addon settings so that might work even better. It can only be changed from guild group or friends menus.

sinnereso 03/28/23 03:48 PM

Quote:

Originally Posted by Baertram (Post 47480)
Here is your RidinDirty.lua file with my changes, hope you understand it better that way seeing the code.
If you got questions, ask ;)

It's untested so please test if it works as expected.

Just wanted to let you know I spent the day going over your changes and have made sense of it and worked it in with only minor changes mostly to variable and function names to better make sense to me. Seems to be working flawlessly. The default saved variable table was nice touch as well and was something I had planned to do later after all the primary stuff was complete. TY again for all your help.

Baertram 03/29/23 05:04 AM

Glad it worked out, yw. Thanks for the feedback.

sinnereso 03/29/23 09:22 AM

I did just have one other super fast question regarding another function im tuning.. am I doing this correctly?

Code:

local _, isRidingGroupMount, hasFreePassengerSlot = GetTargetMountedStateInfo(savedPlayer)
if isRidingGroupMount == false or hasFreePassengerSlot == false then
    blah blah
end

Im just tweaking error handlers and its all complete finally

**EDIT
Seems to be functioning correctly.

Baertram 03/29/23 01:00 PM

You can always have a look at the API documentation txt file
https://wiki.esoui.com/APIVersion#live_API_version
-> link to "API TXT Documentation" .txt file -> Download and open with a text editor

and search for the function name "GetTargetMountedStateInfo" in it.
It will show you the parameters to use and the return variables then:

Code:

* GetTargetMountedStateInfo(*string* _characterOrDisplayName_)
** _Returns:_ *[MountedState|#MountedState]* _mountedState_, *bool* _isRidingGroupMount_, *bool* _hasFreePassengerSlot_

So this function returns 3 parameters.
If you do not need the 1st one "MountedState" you can use the placeholder _ to show that, correct.
And the other 2 return values are _isRidingGroupMount_ and _hasFreePassengerSlot_.

Your code looks okay to me.


All times are GMT -6. The time now is 05:53 PM.

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