All can be done in lua, include the elements that based on secure templates. But it also requires plenty of works to build a whole framework instead of the xml template system.
Here is an example lib
IGAS, it's created without xml templates, it's based on an oop system(
PLoop) so I can make widget classes instead of the xml template. There are widget classes such as TreeView, LayoutPanel, CodeEditor, UnitFrame, UnitPanel(as the raid panel), ActionButton and many others, all be created based on other widget classes.
With the class system, the code will be clear for reading. To create a form in the pic :
test.png
Lua Code:
-- Import the namespace
import "System.Widget"
-- Form is a class that defined in the System.Widget namespace
-- It's a common widget element that used to contains others
local form = Form ("TestF")
-- Caption is the text that displayed on the form header
form.Caption = "Tiny Editor"
-- Message is the text that displayed on the bottom of the form
form.Message = "Input some code and press run"
form.Size = Size(600, 500)
-- lua code editor
local editor = CodeEditor ("Editor", form)
editor.Location = {
AnchorPoint("TOPLEFT", 4, -26),
AnchorPoint("BOTTOMRIGHT", -4, 56),
}
-- the run button
local btn = NormalButton ("Run", form)
btn.Style = "Classic"
btn.Size = Size(100, 24)
btn.Text = "Run"
btn.Location = {
AnchorPoint("BOTTOMRIGHT", -4, 24),
}
-- Run the code when click the button
function btn:OnClick()
pcall( loadstring (editor.Text) )
end
With the oop system, I also can define a whole new class for the above example:
Lua Code:
-- Import the System.Widget namespace
import "System.Widget"
-- Create a new class that inherit from the Form
class "CodeForm"
inherit "Form"
local function run_OnClick(self)
pcall( loadstring (self.Parent.Editor.Text) )
end
-- Init the CodeForm
local function InitializeComponent(self)
self.Caption = "Tiny Editor"
self.Message = "Input some code and press run"
self.Size = Size(600, 500)
-- lua code editor
local editor = CodeEditor ("Editor", self)
editor.Location = {
AnchorPoint("TOPLEFT", 4, -26),
AnchorPoint("BOTTOMRIGHT", -4, 56),
}
-- the run button
local btn = NormalButton ("Run", self)
btn.Style = "Classic"
btn.Size = Size(100, 24)
btn.Text = "Run"
btn.Location = {
AnchorPoint("BOTTOMRIGHT", -4, 24),
}
btn.OnClick = btn.OnClick + run_OnClick
end
-- The Constructor
function CodeForm(self, ...)
-- call super class's constructor
Super(self, ...)
InitializeComponent(self)
end
-- End the definition of the class
endclass "CodeForm"
-- Create an instance of the CodeForm
local form = CodeForm("TestForm")
-- make sure the form is shown
form.Visible = true
It may not be a good example because the whole IGAS lib is a big one and the syntax of the PLoop is too special for common addons.
The xml is not that bad, it's very clear to show the structure of the whole frames, but it's not good at the inheritance. Here is some from the MainMenuBarBagButtons.xml.
Code:
<Frame name="ItemAnimTemplate" virtual="true">
<Scripts>
<OnLoad function="ItemAnim_OnLoad"/>
<OnEvent function="ItemAnim_OnEvent"/>
</Scripts>
</Frame>
<CheckButton name="BagSlotButtonTemplate" inherits="ItemButtonTemplate, ItemAnimTemplate" virtual="true">
<Size x="30" y="30"/>
<Scripts>
<OnLoad>
ItemAnim_OnLoad(self)
PaperDollItemSlotButton_OnLoad(self);
.......
So the BagSlotButtonTemplate should call ItemAnim_OnLoad itself, that means the child template must know what the super template had done.
It's not a big problem, but I just don't like it.