ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   General Authoring Discussion (https://www.esoui.com/forums/forumdisplay.php?f=174)
-   -   XML vs Lua for GUI Best Practices (https://www.esoui.com/forums/showthread.php?t=652)

Yazilliclick 04/06/14 08:57 PM

XML vs Lua for GUI Best Practices
 
I'm just barely getting into addon development and wondering what's considered best practice here or pros and cons against each? I see some addons and some guides that seem to push using Lua over XML for GUI of addons though it's never really explained why. Is there are a time to go with one over the other?

Kith 04/07/14 04:16 AM

Quote:

Originally Posted by Yazilliclick (Post 3038)
I'm just barely getting into addon development and wondering what's considered best practice here or pros and cons against each? I see some addons and some guides that seem to push using Lua over XML for GUI of addons though it's never really explained why. Is there are a time to go with one over the other?

As I found out today, there is either a bug (is what I was told may be the case) or just some extra criteria to allow a LUA created GUI frame to use an OnUpdate handler so keep that in mind when picking between XML and LUA.

My personal preference is to do it all in LUA being brought over from WoW modding.

Xrystal 04/07/14 05:10 AM

My usual preference is to do so as well to keep as much as possible out of the global namespace but it seems some functionality doesn't have a Lua equivalence, or no one has found it yet so I have had to use XML in my addon anyway.

Yazilliclick 04/07/14 06:23 AM

Quote:

Originally Posted by Kith (Post 3066)
As I found out today, there is either a bug (is what I was told may be the case) or just some extra criteria to allow a LUA created GUI frame to use an OnUpdate handler so keep that in mind when picking between XML and LUA.

My personal preference is to do it all in LUA being brought over from WoW modding.

What was the reasoning there with WoW? Believe it's default method was XML with Lua too wasn't it? Thanks for notice on the bug, guessing that's what I'm running smack into as well.

Quote:

Originally Posted by Xrystal (Post 3071)
My usual preference is to do so as well to keep as much as possible out of the global namespace but it seems some functionality doesn't have a Lua equivalence, or no one has found it yet so I have had to use XML in my addon anyway.

Ah good point about global clutter thanks!

Halja 04/07/14 09:40 AM

It not an either XML or LUA best practice for GUI construction. As it’s been said, there are pros and cons to weigh because not everything is documented, a feature is not exposed, or construction is cleaner in one or the other. Some have even noticed an occasional runtime differences. Personally, I’m taking a hybrid approach. I will define the fixed UI elements in XML. On the dynamically created controls, I’ll use XML defined virtual templates. Then in LUA code call CreateControlFromVirtual(). Its what's comfortable for me.
--halja

Dio 04/07/14 12:15 PM

Either way works. XML certainly makes it easier to see the hierarchy of your GUI. As a web developer I've just been conditioned against XML, having begrudgingly worked with it in years past, and it's sort of become less relevant in favor of JSON. If I was designing a unit frame addon I would probably use XML, but to me it's not necessary for a simple addon that uses a few frames generated imperatively.

Errc 04/07/14 12:55 PM

Personally I use Lua for everything. It is just significantly easier to create and modify when all of the code is written in Lua. You can find a chaining function in Zgoo that makes assigning properties and setting up UI even easier, discussed here as well.

The only advantage I have seen to writing in xml is it is slightly easier to identify the hierarchy, but templates and UI creation are easier to do in Lua and provide you with more functionality.

To replace templates I usually just make a new "class" in Lua and use that.

Example toplevel frame class.
Code:

function Frame:New(parent,name)
  local frame = CHAIN(ui:CreateControl(name,parent,CT_TOPLEVELCONTROL,Frame))
  :SetClampedToScreen(true)
  .__END

  frame.bd = ui:Create("Backdrop",frame,name and name.."_BD")

  return frame
 end

 function Frame:SetCanDrag(drag)
  if drag then
  self:SetMovable(true)
  self:SetMouseEnabled(true)
  else
  self:SetMovable(false)
  self:SetMouseEnabled(false)
  end
 end

So this class just creates a simple top level frame with a backdrop, and has a custom function for making it draggable.

To use this you just
Code:

local newFrame = CHAIN(Frame:New(GuiRoot,"MyNewFrameName"))
  :SetAnchor(CENTER)
  :SetCanDrag(true)
 .__END

There are some implementation details to getting it set up correctly to inherit custom functions and the rest of that jazz, but that is my experience.

Xrystal 04/07/14 02:14 PM

I had all but the update routine in lua for my gatherer addon until I hit a glitch with a new frame functionality that I have yet to see a lua equivalent for the ZO_ComboBox control that works and my thread http://www.esoui.com/forums/showthread.php?t=573 asking about it has yet to solve the problem. So, to save myself from waiting around and holding back the addon while I figure it out I just converted the whole addon to use the XML for visual and Lua for functionality.

I can always change it later on when a solution has been found to allow a non global way of creating frames this way.

Seerah 04/07/14 02:35 PM

Is ZO_ComboBox different from ZO_Options_Dropdown?

Xrystal 04/07/14 02:57 PM

I have no idea. It's one of those undocumented items that I have managed to get working looking at Pawkette's console addon.

The problem is the Lua code :
tlw.ZoneList.DropDown = ZO_ComboBox_ObjectFromContainer( tlw.ZoneList )

This line works when the main control is created in XML but not when created in Lua. I suspect there is something that is missing from the Lua code that is needed that isn't needed when using the XML way of creating it.

There is no mention in the XML or Lua of ZO_Options_Dropdown but who knows what is in the ESO Lua code that we can't see. But yes combobox is another description of a dropdown menu. So could be the same thing.

Kith 04/07/14 03:36 PM

Quote:

Originally Posted by Yazilliclick (Post 3078)
What was the reasoning there with WoW? Believe it's default method was XML with Lua too wasn't it? Thanks for notice on the bug, guessing that's what I'm running smack into as well.



Ah good point about global clutter thanks!

I believe it was, as you said, global clutter. XML frames needed a globally defined name to be referenced whereas with LUA you could not give the frame a name and reference it through saving its return to a local. Most WoW mods in the latter days would only have 2 globals, the mod table itself and its SavedVariables table.

With my 2-part library (due to the OnUpdate XML thing), my mod is up to 5 globals which bugs me more than it should :P

Seerah 04/07/14 04:08 PM

Xrystal: look at LibAddonMenu to see how I create dropdowns

Xrystal 04/07/14 04:18 PM

Quote:

Originally Posted by Seerah (Post 3199)
Xrystal: look at LibAddonMenu to see how I create dropdowns

That was my first port of call but your way kept asking for panelID which of course doesn't exist outside of the settings/options setup.

It's no biggie, it's not like I have more than 1 addon floating around the system flooding the system with global frames. And it is a way for me to learn XML rofl. Didn't know Lua until I wrote wow addons, may as well learn XML writing addons for ESO.

Seerah 04/07/14 04:20 PM

I'll try to remember to type up something that's easy to follow, then, when I get home later tonight. Those dropdowns are for use in the settings menu, so I used a couple of the functions set to the template to make stuff easier - maybe that's what is confusing you. :) (I also haven't looked at that part of the code in a couple of months or so...)

Xrystal 04/07/14 04:34 PM

It would be appreciated Seerah :banana: I'm sure I'm not the only one that looks at it and goes 'errrrrr'. I don't suppose ESO ever did the WoW thing and make an addon wide table to use so we can have multiple files and still not leak into global space ? I loved it when they did that.

Kith 04/07/14 06:45 PM

Quote:

Originally Posted by Xrystal (Post 3205)
It would be appreciated Seerah :banana: I'm sure I'm not the only one that looks at it and goes 'errrrrr'. I don't suppose ESO ever did the WoW thing and make an addon wide table to use so we can have multiple files and still not leak into global space ? I loved it when they did that.

That wasn't a wow thing as such, it was part of the Ace Library. They declared a single global namespace table, AceAddon or some such, and anybody who used the lib could declare their addon's table in that and reference it the same way. So only one global entry as a reference that any of your mod files could pull from.

I wonder if its possible to make a similiar 'base' lib for that type of functionality, though I don't nearly have enough understanding of the 'low level' metatable handling to implement embeddable libs like AceLib did.

Xrystal 04/07/14 07:07 PM

Quote:

Originally Posted by Kith (Post 3224)
That wasn't a wow thing as such, it was part of the Ace Library. They declared a single global namespace table, AceAddon or some such, and anybody who used the lib could declare their addon's table in that and reference it the same way. So only one global entry as a reference that any of your mod files could pull from.

I wonder if its possible to make a similiar 'base' lib for that type of functionality, though I don't nearly have enough understanding of the 'low level' metatable handling to implement embeddable libs like AceLib did.

I never used Ace in any of my wow addons. WoW added a new functionality around version 3.0 where you could put local addonName, addonData = ... at the top of every file in your addon to access a common data table between them. If they used Ace inside WoW as standard it was never documented as such.

Seerah 04/07/14 10:17 PM

Xrystal is correct. This was something the WoW devs added to the API (though I thought it was later than 3.0). ESO does not have anything like this currently, though who knows what they'll do - it is new, after all.

I have a few minutes now, let me take a look at that code I was going to post...

Seerah 04/07/14 11:04 PM

Okay, so... ZO_Options_Dropdown is the template used for the settings menus. This includes a base frame, the options text on the left and a dropdown on the right. The actual dropdown object does inherit from ZO_ComboBox.

SO. I went through the API and all the stuff I have *ahem* and wrote this up from scratch, based on the dropdown to select your guild in the guild window. I booted up the launcher to log in to check it, but I see there's a patch. And it's downloading at about 60 kb/s at the moment. So... untested. :) It's my bedtime. :rolleyes:

Lua Code:
  1. local wm = WINDOW_MANAGER
  2. local choices = {"apple", "banana", "cherry"}
  3.  
  4. local myFrame = wm:CreateTopLevelWindow("myFrameForXrystal")
  5.     myFrame:SetAnchor(CENTER)
  6.     myFrame:SetDimensions(200, 50)
  7. local dropdownContainer = wm:CreateControl("myFrameForXrystalDropdown", myFrame, CT_CONTROL)
  8.     dropdownContainer:SetHandler("OnMouseUp", ZO_ComboBox_DropdownClicked)
  9.     dropdownContainer:SetAnchor(CENTER)
  10. local selected = wm:CreateControl("myFrameForXrystalDropdownSelected", dropdownContainer, CT_LABEL)
  11.     selected:SetAnchor(TOPLEFT)
  12.     selected:SetColor(GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_SELECTED)
  13. local open = wm:CreateControlFromVirtual("myFrameForXrystalDropdownOpen", dropdownContainer, "ZO_DropdownButton")
  14.     open:SetDimensions(16,16)
  15.     open:SetAnchor(LEFT, selected, RIGHT, 3, 0)
  16. local dropdown = ZO_ComboBox:New(dropdownContainer)
  17.  
  18. local function OnItemSelect(entryText, entry)
  19.     d(entryText, entry)
  20. end
  21.  
  22. for i=1,#choices do
  23.     local entry = dropdown:CreateItemEntry(choices[i], OnItemSelect)  --this really just creates a table with {name = choices[i], callback = OnItemSelect} - you may be able to skip this step...
  24.     dropdown:AddItem(entry)  --again, entry is just a table with the above args stored in it
  25. end

Patch is at 10%. Guess I'll leave that running overnight... Hope this works! :D

Xrystal 04/08/14 05:43 AM

1 Attachment(s)
Thanks Seerah, I'll let you know. I went to bed before I even saw this myself. Couldn't keep my eyes open any longer rofl.

edit:

Nada, I even added a backdrop to make things easier to see but cannot see the dropdown arrow anywhere on the screen. But it also isn't triggering any errors.

I tried putting it in a function and display debug text to see if it was getting in there and the whole addon wasn't apparently working ... maybe it doesn't like my name of ZO_ComboBoxTest as an addon name but it is okay with ZO_ObjectTest rofl.


edit2:
Erm, note to self and make sure the files listed in the txt file are EXACTLY the same as the ones used and not missing a letter ... testing again


edit3:
It displays but clicking the dropdown arrow does squat. Oh wait there is something missing in your code that was in Pawkette's let me see what it is.

edit4:
Yes the following code in Pawkette was missing from the lua
Lua Code:
  1. <Button name="$(parent)OpenDropdown" inherits="ZO_DropdownButton">
  2.                             <Dimensions x="16" y="16" />
  3.                             <Anchor point="TOPRIGHT"/>
  4.                             <OnClicked>
  5.                                 ZO_ComboBox_DropdownClicked(self:GetParent())
  6.                             </OnClicked>
  7.                         </Button>
So added the OnClicked handler into the mix to see if that worked ..
Lua Code:
  1. local open = wm:CreateControlFromVirtual("myFrameForXrystalDropdownOpen", dropdownContainer, "ZO_DropdownButton")
  2. open:SetDimensions(16,16)
  3. open:SetAnchor(LEFT, selected, RIGHT, 3, 0)
  4. open:SetHandler("OnClicked",function() ZO_ComboBox_DropdownClicked(self:GetParent()) end)

et voila .. the same problem I was getting in my code ..

error on line 20 which is the new SetHandler line I added :
Lua Code:
  1. user:/AddOns/ZO_ComboBoxTest/ZO_ComboBoxTest.lua:20: attempt to index a nil value
  2. stack traceback:
  3.     user:/AddOns/ZO_ComboBoxTest/ZO_ComboBoxTest.lua:20: in function '(anonymous)'

So the question seems to be why does it make it work being in the xml but errors out when it isn't

edit 5:
self didn't exist .. changed that line so it says :
open:SetHandler("OnClicked",function(self) ZO_ComboBox_DropdownClicked(self:GetParent()) end)

And it worked .. apart from setting the selected text .. another slight tweak to the code ...
First picture is this part working.

edit 6:
Looks like the following code block from Pawkette's code needs to be somewhere in your example but cannot see where it fits:
Lua Code:
  1. local dropDown = ZO_ComboBox_ObjectFromContainer( comboBox )
  2. dropDown:SetSelectedItemFont( 'ZoFontGameLarge' )
  3. dropDown:SetDropdownFont( 'ZoFontGame' )
  4. dropDown:SetSpacing( 8 )
  5. dropDown:SetSelectedItem( dropDown.SelectedItem )
  6. --dropDown.Button = self:GetNamedChild(name.."OpenDropdown")

Looking at the Button reference I tried it (minus the ObjectFromContainer line) in with your dropdown code and your selected code but both triggered the following error where the line mentioned is the SetSelectedItemFont line inferring it never got created ..

edit 7:
There is also this element in the CT_CONTROL combox Box xml code that seems to not be in your code block and I believe this is the code that allows the text side of the control to resize based on the selected text ... which is what the extra code mentioned above relates to.

Lua Code:
  1. resizeToFitDescendents="true"

Still no joy figuring this out, but hopefully your erm .. extra info will identify where this needs to go to work properly.

And if I haven't already said it, thanks again Seerah.


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

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