Reactive properties #65

Merged
thesabinelim merged 4 commits from dynamic-attributes into master 2023-05-08 18:03:50 +08:00
2 changed files with 636 additions and 211 deletions

View File

@@ -8,6 +8,7 @@ local function newNode(name)
node.___name = name node.___name = name
node.___children = {} node.___children = {}
node.___props = {} node.___props = {}
node.___reactiveProps = {}
function node:value() return self.___value end function node:value() return self.___value end
function node:setValue(val) self.___value = val end function node:setValue(val) self.___value = val end
@@ -43,7 +44,12 @@ local function newNode(name)
else else
self[lName] = value self[lName] = value
end end
table.insert(self.___props, { name = name, value = self[name] }) table.insert(self.___props, { name = name, value = self[lName] })
end
function node:reactiveProperties() return self.___reactiveProps end
function node:addReactiveProperty(name, value)
self.___reactiveProps[name] = value
end end
return node return node
@@ -80,12 +86,18 @@ function XmlParser:FromXmlString(value)
return value; return value;
end end
function XmlParser:ParseArgs(node, s) function XmlParser:ParseProps(node, s)
string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a) string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a)
node:addProperty(w, self:FromXmlString(a)) node:addProperty(w, self:FromXmlString(a))
end) end)
end end
function XmlParser:ParseReactiveProps(node, s)
string.gsub(s, "(%w+)={(.-)}", function(w, a)
node:addReactiveProperty(w, a)
end)
end
function XmlParser:ParseXmlText(xmlText) function XmlParser:ParseXmlText(xmlText)
local stack = {} local stack = {}
local top = newNode() local top = newNode()
@@ -102,11 +114,13 @@ function XmlParser:ParseXmlText(xmlText)
end end
if empty == "/" then -- empty element tag if empty == "/" then -- empty element tag
local lNode = newNode(label) local lNode = newNode(label)
self:ParseArgs(lNode, xarg) self:ParseProps(lNode, xarg)
self:ParseReactiveProps(lNode, xarg)
top:addChild(lNode) top:addChild(lNode)
elseif c == "" then -- start tag elseif c == "" then -- start tag
local lNode = newNode(label) local lNode = newNode(label)
self:ParseArgs(lNode, xarg) self:ParseProps(lNode, xarg)
self:ParseReactiveProps(lNode, xarg)
table.insert(stack, lNode) table.insert(stack, lNode)
top = lNode top = lNode
else -- end tag else -- end tag
@@ -130,24 +144,6 @@ function XmlParser:ParseXmlText(xmlText)
return top return top
end end
function XmlParser:loadFile(xmlFilename, base)
if not base then
base = ""
end
local path = fs.combine(base, xmlFilename)
local hFile, err = io.open(path, "r");
if hFile and not err then
local xmlText = hFile:read("*a"); -- read file content
io.close(hFile);
return self:ParseXmlText(xmlText), nil;
else
print(err)
return nil
end
end
local function executeScript(scripts) local function executeScript(scripts)
for k,v in pairs(scripts)do for k,v in pairs(scripts)do
if(k~="env")then if(k~="env")then
@@ -178,16 +174,58 @@ return {
VisualObject = function(base, basalt) VisualObject = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
local x, y = self:getPosition()
local w, h = self:getSize()
if (name == "x") then
self:setPosition(value, y)
elseif (name == "y") then
self:setPosition(x, value)
elseif (name == "width") then
self:setSize(value, h)
elseif (name == "height") then
self:setSize(w, value)
elseif (name == "background") then
self:setBackground(colors[value])
elseif (name == "foreground") then
self:setForeground(colors[value])
end
end,
updateSpecifiedValuesByXMLData = function(self, data, valueNames)
for _, name in ipairs(valueNames) do
local value = xmlValue(name, data)
if (value ~= nil) then
self:updateValue(name, value)
end
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
scripts.env[self:getName()] = self scripts.env[self:getName()] = self
local x, y = self:getPosition() for k,v in pairs(data:reactiveProperties()) do
local w, h = nil, nil local sharedVariable = string.sub(v, 8, -1)
if(xmlValue("x", data)~=nil)then x = xmlValue("x", data) end local sharedObservers = scripts.env.sharedObservers
if(xmlValue("y", data)~=nil)then y = xmlValue("y", data) end if (sharedObservers[sharedVariable]) == nil then
if(xmlValue("width", data)~=nil)then w = xmlValue("width", data) end sharedObservers[sharedVariable] = {}
if(xmlValue("height", data)~=nil)then h = xmlValue("height", data) end end
if(xmlValue("background", data)~=nil)then self:setBackground(colors[xmlValue("background", data)]) end table.insert(
if(xmlValue("foreground", data)~=nil)then self:setForeground(colors[xmlValue("foreground", data)]) end sharedObservers[sharedVariable],
function(val)
self:updateValue(k, val)
end
)
end
self:updateSpecifiedValuesByXMLData(data, {
"x",
"y",
"width",
"height",
"background",
"foreground"
})
if(xmlValue("script", data)~=nil)then if(xmlValue("script", data)~=nil)then
@@ -203,13 +241,6 @@ return {
registerFunctionEvent(self, xmlValue(v, data), self[v], scripts) registerFunctionEvent(self, xmlValue(v, data), self[v], scripts)
end end
end end
self:setPosition(x, y)
if(w~=nil or h~=nil)then
local w1, h1 = self:getSize()
if w==nil then w = w1 end
if h==nil then h = h1 end
self:setSize(w, h)
end
return self return self
end, end,
@@ -219,9 +250,19 @@ return {
ChangeableObject = function(base, basalt) ChangeableObject = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "value") then
self:setValue(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("value", data)~=nil)then self:setValue(xmlValue("value", data)) end self:updateSpecifiedValuesByXMLData(data, {
"value"
})
if(xmlValue("onChange", data)~=nil)then if(xmlValue("onChange", data)~=nil)then
registerFunctionEvent(self, xmlValue("onChange", data), self.onChange, scripts) registerFunctionEvent(self, xmlValue("onChange", data), self.onChange, scripts)
end end
@@ -252,13 +293,24 @@ return {
end end
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local xOffset, yOffset = self:getOffset()
if (name == "layout") then
self:setLayout(value)
elseif (name == "xOffset") then
self:setOffset(value, yOffset)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
lastXMLReferences = {} lastXMLReferences = {}
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local xOffset, yOffset = self:getOffset() self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("layout", data)~=nil)then self:loadLayout(xmlValue("layout", data)) end "layout",
if(xmlValue("xOffset", data)~=nil)then xOffset = xmlValue("xOffset", data) end "xOffset"
self:setOffset(xOffset, yOffset) })
local objectList = data:children() local objectList = data:children()
local _OBJECTS = basalt.getObjects() local _OBJECTS = basalt.getObjects()
@@ -286,6 +338,22 @@ return {
scripts.env = _ENV scripts.env = _ENV
scripts.env.basalt = basalt scripts.env.basalt = basalt
scripts.env.shared = {} scripts.env.shared = {}
scripts.env.sharedObservers = {}
local shared = {}
setmetatable(scripts.env.shared, {
__index = function(_, k)
return shared[k]
end,
__newindex = function(_, k, v)
local observers = scripts.env.sharedObservers[k]
if observers ~= nil then
for _,observer in pairs(observers) do
observer(v)
end
end
shared[k] = v
end
})
local f = fs.open(path, "r") local f = fs.open(path, "r")
local data = XmlParser:ParseXmlText(f.readAll()) local data = XmlParser:ParseXmlText(f.readAll())
f.close() f.close()
@@ -321,13 +389,26 @@ return {
end end
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local xOffset, yOffset = self:getOffset()
if (name == "layout") then
self:setLayout(value)
elseif (name == "xOffset") then
self:setOffset(value, yOffset)
elseif (name == "yOffset") then
self:setOffset(xOffset, value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local xOffset, yOffset = self:getOffset() self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("layout", data)~=nil)then self:loadLayout(xmlValue("layout", data)) end "layout",
if(xmlValue("xOffset", data)~=nil)then xOffset = xmlValue("xOffset", data) end "xOffset",
if(xmlValue("yOffset", data)~=nil)then yOffset = xmlValue("yOffset", data) end "yOffset"
self:setOffset(xOffset, yOffset) })
local objectList = data:children() local objectList = data:children()
local _OBJECTS = basalt.getObjects() local _OBJECTS = basalt.getObjects()
@@ -356,6 +437,22 @@ return {
scripts.env.basalt = basalt scripts.env.basalt = basalt
scripts.env.main = self scripts.env.main = self
scripts.env.shared = {} scripts.env.shared = {}
scripts.env.sharedObservers = {}
local shared = {}
setmetatable(scripts.env.shared, {
__index = function(_, k)
return shared[k]
end,
__newindex = function(_, k, v)
local observers = scripts.env.sharedObservers[k]
if observers ~= nil then
for _,observer in pairs(observers) do
observer(v)
end
end
shared[k] = v
end
})
local f = fs.open(path, "r") local f = fs.open(path, "r")
local data = XmlParser:ParseXmlText(f.readAll()) local data = XmlParser:ParseXmlText(f.readAll())
f.close() f.close()
@@ -371,11 +468,28 @@ return {
Flexbox = function(base, basalt) Flexbox = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "flexDirection") then
self:setFlexDirection(value)
elseif (name == "justifyContent") then
self:setJustifyContent(value)
elseif (name == "alignItems") then
self:setAlignItems(value)
elseif (name == "spacing") then
self:setSpacing(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("flexDirection", data)~=nil)then self:setFlexDirection(xmlValue("flexDirection", data)) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("justifyContent", data)~=nil)then self:setJustifyContent(xmlValue("justifyContent", data)) end "flexDirection",
if(xmlValue("spacing", data)~=nil)then self:setSpacing(xmlValue("spacing", data)) end "justifyContent",
"alignItems",
"spacing"
})
return self return self
end, end,
} }
@@ -384,11 +498,25 @@ return {
Button = function(base, basalt) Button = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "text") then
self:setText(value)
elseif (name == "horizontalAlign") then
self:setHorizontalAlign(value)
elseif (name == "verticalAlign") then
self:setVerticalAlign(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("horizontalAlign", data)~=nil)then self:setHorizontalAlign(xmlValue("horizontalAlign", data)) end "text",
if(xmlValue("verticalAlign", data)~=nil)then self:setText(xmlValue("verticalAlign", data)) end "horizontalAlign",
"verticalAlign"
})
return self return self
end, end,
} }
@@ -397,10 +525,22 @@ return {
Label = function(base, basalt) Label = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "text") then
self:setText(value)
elseif (name == "align") then
self:setAlign(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("align", data)~=nil)then self:setTextAlign(xmlValue("align", data)) end "text",
"align"
})
return self return self
end, end,
} }
@@ -409,17 +549,38 @@ return {
Input = function(base, basalt) Input = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local defaultText, defaultFG, defaultBG = self:getDefaultText()
if (name == "defaultText") then
self:setDefaultText(value, defaultFG, defaultBG)
elseif (name == "defaultFG") then
self:setDefaultText(defaultText, value, defaultBG)
elseif (name == "defaultBG") then
self:setDefaultText(defaultText, defaultFG, value)
elseif (name == "offset") then
self:setOffset(value)
elseif (name == "textOffset") then
self:setTextOffset(value)
elseif (name == "text") then
self:setText(value)
elseif (name == "inputLimit") then
self:setInputLimit(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local defaultText, defaultFG, defaultBG = self:getDefaultText() self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("defaultText", data)~=nil)then defaultText = xmlValue("defaultText", data) end "defaultText",
if(xmlValue("defaultFG", data)~=nil)then defaultFG = xmlValue("defaultFG", data) end "defaultFG",
if(xmlValue("defaultBG", data)~=nil)then defaultBG = xmlValue("defaultBG", data) end "defaultBG",
self:setDefaultText(defaultText, defaultFG, defaultBG) "offset",
if(xmlValue("offset", data)~=nil)then self:setOffset(xmlValue("offset", data)) end "textOffset",
if(xmlValue("textOffset", data)~=nil)then self:setTextOffset(xmlValue("textOffset", data)) end "text",
if(xmlValue("text", data)~=nil)then self:setValue(xmlValue("text", data)) end "inputLimit"
if(xmlValue("inputLimit", data)~=nil)then self:setInputLimit(xmlValue("inputLimit", data)) end })
return self return self
end, end,
} }
@@ -428,15 +589,33 @@ return {
Image = function(base, basalt) Image = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local xOffset, yOffset = self:getOffset()
if (name == "xOffset") then
self:setOffset(value, yOffset)
elseif (name == "yOffset") then
self:setOffset(xOffset, value)
elseif (name == "path") then
self:loadImage(value)
elseif (name == "usePalette") then
self:usePalette(value)
elseif (name == "play") then
self:play(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local xOffset, yOffset = self:getOffset() local xOffset, yOffset = self:getOffset()
if(xmlValue("xOffset", data)~=nil)then xOffset = xmlValue("xOffset", data) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("yOffset", data)~=nil)then yOffset = xmlValue("yOffset", data) end "xOffset",
self:setOffset(xOffset, yOffset) "yOffset",
if(xmlValue("path", data)~=nil)then self:loadImage(xmlValue("path", data)) end "path",
if(xmlValue("usePalette", data)~=nil)then self:usePalette(xmlValue("usePalette", data)) end "usePalette",
if(xmlValue("play", data)~=nil)then self:play(xmlValue("play", data)) end "play"
})
return self return self
end, end,
} }
@@ -445,15 +624,32 @@ return {
Checkbox = function(base, basalt) Checkbox = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local activeSymbol, inactiveSymbol = self:getSymbol()
if (name == "text") then
self:setText(value)
elseif (name == "checked") then
self:setChecked(value)
elseif (name == "textPosition") then
self:setTextPosition(value)
elseif (name == "activeSymbol") then
self:setSymbol(value, inactiveSymbol)
elseif (name == "inactiveSymbol") then
self:setSymbol(activeSymbol, value)
end
end,
setValuesByXMLData = function(self, dat, scriptsa) setValuesByXMLData = function(self, dat, scriptsa)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local activeSymbol, inactiveSymbol = self:getSymbol() self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end "text",
if(xmlValue("checked", data)~=nil)then self:setChecked(xmlValue("checked", data)) end "checked",
if(xmlValue("textPosition", data)~=nil)then self:setTextPosition(xmlValue("textPosition", data)) end "textPosition",
if(xmlValue("activeSymbol", data)~=nil)then activeSymbol = xmlValue("activeSymbol", data) end "activeSymbol",
if(xmlValue("inactiveSymbol", data)~=nil)then inactiveSymbol = xmlValue("inactiveSymbol", data) end "inactiveSymbol"
self:setSymbol(activeSymbol, inactiveSymbol) })
return self return self
end, end,
} }
@@ -462,9 +658,19 @@ return {
Program = function(base, basalt) Program = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "execute") then
self:execute(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("execute", data)~=nil)then self:execute(xmlValue("execute", data)) end self:updateSpecifiedValuesByXMLData(data, {
"execute"
})
return self return self
end, end,
} }
@@ -473,15 +679,35 @@ return {
Progressbar = function(base, basalt) Progressbar = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local activeBarColor, activeBarSymbol, activeBarSymbolCol = self:getProgressBar()
if (name == "direction") then
self:setDirection(value)
elseif (name == "activeBarColor") then
self:setProgressBar(value, activeBarSymbol, activeBarSymbolCol)
elseif (name == "activeBarSymbol") then
self:setProgressBar(activeBarColor, value, activeBarSymbolCol)
elseif (name == "activeBarSymbolColor") then
self:setProgressBar(activeBarColor, activeBarSymbol, value)
elseif (name == "backgroundSymbol") then
self:setBackgroundSymbol(value)
elseif (name == "progress") then
self:setProgress(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local activeBarColor, activeBarSymbol, activeBarSymbolCol = self:getProgressBar() self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("direction", data)~=nil)then self:setDirection(xmlValue("direction", data)) end "direction",
if(xmlValue("activeBarColor", data)~=nil)then activeBarColor = colors[xmlValue("activeBarColor", data)] end "activeBarColor",
if(xmlValue("activeBarSymbol", data)~=nil)then activeBarSymbol = xmlValue("activeBarSymbol", data) end "activeBarSymbol",
if(xmlValue("activeBarSymbolColor", data)~=nil)then activeBarSymbolCol = colors[xmlValue("activeBarSymbolColor", data)] end "activeBarSymbolColor",
if(xmlValue("backgroundSymbol", data)~=nil)then self:setBackgroundSymbol(xmlValue("backgroundSymbol", data)) end "backgroundSymbol",
if(xmlValue("progress", data)~=nil)then self:setProgress(xmlValue("progress", data)) end "progress"
})
return self return self
end, end,
} }
@@ -490,13 +716,31 @@ return {
Slider = function(base, basalt) Slider = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "symbol") then
self:setSymbol(value)
elseif (name == "symbolColor") then
self:setSymbolColor(value)
elseif (name == "index") then
self:setIndex(value)
elseif (name == "maxValue") then
self:setMaxValue(value)
elseif (name == "barType") then
self:setBarType(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("symbol", data)~=nil)then self:setSymbol(xmlValue("symbol", data)) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("symbolColor", data)~=nil)then self:setSymbolColor(xmlValue("symbolColor", data)) end "symbol",
if(xmlValue("index", data)~=nil)then self:setIndex(xmlValue("index", data)) end "symbolColor",
if(xmlValue("maxValue", data)~=nil)then self:setIndex(xmlValue("maxValue", data)) end "index",
if(xmlValue("barType", data)~=nil)then self:setBarType(xmlValue("barType", data)) end "maxValue",
"barType"
})
return self return self
end, end,
} }
@@ -505,15 +749,37 @@ return {
Scrollbar = function(base, basalt) Scrollbar = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "symbol") then
self:setSymbol(value)
elseif (name == "symbolColor") then
self:setSymbolColor(value)
elseif (name == "symbolSize") then
self:setSymbolSize(value)
elseif (name == "scrollAmount") then
self:setScrollAmount(value)
elseif (name == "index") then
self:setIndex(value)
elseif (name == "maxValue") then
self:setMaxValue(value)
elseif (name == "barType") then
self:setBarType(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("symbol", data)~=nil)then self:setSymbol(xmlValue("symbol", data)) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("symbolColor", data)~=nil)then self:setSymbolColor(xmlValue("symbolColor", data)) end "symbol",
if(xmlValue("symbolSize", data)~=nil)then self:setSymbolSize(xmlValue("symbolSize", data)) end "symbolColor",
if(xmlValue("scrollAmount", data)~=nil)then self:setScrollAmount(xmlValue("scrollAmount", data)) end "symbolSize",
if(xmlValue("index", data)~=nil)then self:setIndex(xmlValue("index", data)) end "scrollAmount",
if(xmlValue("maxValue", data)~=nil)then self:setIndex(xmlValue("maxValue", data)) end "index",
if(xmlValue("barType", data)~=nil)then self:setBarType(xmlValue("barType", data)) end "maxValue",
"barType"
})
return self return self
end, end,
} }
@@ -522,9 +788,19 @@ return {
MonitorFrame = function(base, basalt) MonitorFrame = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "monitor") then
self:setMonitor(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("monitor", data)~=nil)then self:setSymbol(xmlValue("monitor", data)) end self:updateSpecifiedValuesByXMLData(data, {
"monitor"
})
return self return self
end, end,
} }
@@ -533,11 +809,25 @@ return {
Switch = function(base, basalt) Switch = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "symbol") then
self:setSymbol(value)
elseif (name == "activeBackground") then
self:setActiveBackground(value)
elseif (name == "inactiveBackground") then
self:setInactiveBackground(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("symbol", data)~=nil)then self:setSymbol(xmlValue("symbol", data)) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("activeBackground", data)~=nil)then self:setActiveBackground(xmlValue("activeBackground", data)) end "symbol",
if(xmlValue("inactiveBackground", data)~=nil)then self:setInactiveBackground(xmlValue("inactiveBackground", data)) end "activeBackground",
"inactiveBackground"
})
return self return self
end, end,
} }
@@ -546,16 +836,30 @@ return {
Textfield = function(base, basalt) Textfield = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local fgSel, bgSel = self:getSelection()
local xOffset, yOffset = self:getOffset()
if (name == "bgSelection") then
self:setSelection(fgSel, value)
elseif (name == "fgSelection") then
self:setSelection(value, bgSel)
elseif (name == "xOffset") then
self:setOffset(value, yOffset)
elseif (name == "yOffset") then
self:setOffset(xOffset, value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local bgSel, fgSel = self:getSelection() self:updateSpecifiedValuesByXMLData(data, {
local xOffset, yOffset = self:getOffset() "bgSelection",
if(xmlValue("bgSelection", data)~=nil)then bgSel = xmlValue("bgSelection", data) end "fgSelection",
if(xmlValue("fgSelection", data)~=nil)then fgSel = xmlValue("fgSelection", data) end "xOffset",
if(xmlValue("xOffset", data)~=nil)then xOffset = xmlValue("xOffset", data) end "yOffset"
if(xmlValue("yOffset", data)~=nil)then yOffset = xmlValue("yOffset", data) end })
self:setSelection(fgSel, bgSel)
self:setOffset(xOffset, yOffset)
if(data["lines"]~=nil)then if(data["lines"]~=nil)then
@@ -615,10 +919,22 @@ return {
Timer = function(base, basalt) Timer = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "start") then
self:start(value)
elseif (name == "time") then
self:setTime(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("start", data)~=nil)then self:start(xmlValue("start", data)) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("time", data)~=nil)then self:setTime(xmlValue("time", data)) end "start",
"time"
})
if(xmlValue("onCall", data)~=nil)then if(xmlValue("onCall", data)~=nil)then
registerFunctionEvent(self, xmlValue("onCall", data), self.onCall, scripts) registerFunctionEvent(self, xmlValue("onCall", data), self.onCall, scripts)
@@ -631,16 +947,32 @@ return {
List = function(base, basalt) List = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local selBg, selFg = self:getSelectionColor()
if (name == "align") then
self:setTextAlign(value)
elseif (name == "offset") then
self:setOffset(value)
elseif (name == "selectionBg") then
self:setSelectionColor(value, selFg)
elseif (name == "selectionFg") then
self:setSelectionColor(selBg, value)
elseif (name == "scrollable") then
self:setScrollable(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local selBg, selFg = self:getSelectionColor() self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("align", data)~=nil)then self:setTextAlign(xmlValue("align", data)) end "align",
if(xmlValue("offset", data)~=nil)then self:setOffset(xmlValue("offset", data)) end "offset",
if(xmlValue("selectionBg", data)~=nil)then selBg = xmlValue("selectionBg", data) end "selectionBg",
if(xmlValue("selectionFg", data)~=nil)then selFg = xmlValue("selectionFg", data) end "selectionFg",
self:setSelectionColor(selBg, selFg) "scrollable"
})
if(xmlValue("scrollable", data)~=nil)then self:setScrollable(xmlValue("scrollable", data)) end
if(data["item"]~=nil)then if(data["item"]~=nil)then
local tab = data["item"] local tab = data["item"]
@@ -659,12 +991,23 @@ return {
Dropdown = function(base, basalt) Dropdown = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local w, h = self:getDropdownSize()
if (name == "dropdownWidth") then
self:setDropdownSize(value, h)
elseif (name == "dropdownHeight") then
self:setDropdownSize(w, value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local w, h = self:getDropdownSize() self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("dropdownWidth", data)~=nil)then w = xmlValue("dropdownWidth", data) end "dropdownWidth",
if(xmlValue("dropdownHeight", data)~=nil)then h = xmlValue("dropdownHeight", data) end "dropdownHeight"
self:setDropdownSize(w, h) })
return self return self
end, end,
} }
@@ -673,18 +1016,30 @@ return {
Radio = function(base, basalt) Radio = function(base, basalt)
local object = { local object = {
setValuesByXMLData = function(self, data, scripts) updateValue = function(self, name, value)
base.setValuesByXMLData(self, data, scripts) if (value == null) then return end
base.updateValue(self, name, value)
local selBg, selFg = self:getBoxSelectionColor() local selBg, selFg = self:getBoxSelectionColor()
local defBg, defFg = self:setBoxDefaultColor() local defBg, defFg = self:setBoxDefaultColor()
if (name == "selectionBg") then
self:setBoxSelectionColor(value, selFg)
elseif (name == "selectionFg") then
self:setBoxSelectionColor(selBg, value)
elseif (name == "defaultBg") then
self:setBoxDefaultColor(value, defFg)
elseif (name == "defaultFg") then
self:setBoxDefaultColor(defBg, value)
end
end,
if(xmlValue("selectionBg", data)~=nil)then selBg = xmlValue("selectionBg", data) end setValuesByXMLData = function(self, data, scripts)
if(xmlValue("selectionFg", data)~=nil)then selFg = xmlValue("selectionFg", data) end base.setValuesByXMLData(self, data, scripts)
self:setBoxSelectionColor(selBg, selFg) self:updateSpecifiedValuesByXMLData(data, {
"selectionBg",
if(xmlValue("defaultBg", data)~=nil)then defBg = xmlValue("defaultBg", data) end "selectionFg",
if(xmlValue("defaultFg", data)~=nil)then defFg = xmlValue("defaultFg", data) end "defaultBg",
self:setBoxDefaultColor(defBg, defFg) "defaultFg"
})
if(data["item"]~=nil)then if(data["item"]~=nil)then
local tab = data["item"] local tab = data["item"]
@@ -701,10 +1056,22 @@ return {
Menubar = function(base, basalt) Menubar = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
if (name == "space") then
self:setSpace(value)
elseif (name == "scrollable") then
self:setScrollable(value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
if(xmlValue("space", data)~=nil)then self:setSpace(xmlValue("space", data)) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("scrollable", data)~=nil)then self:setScrollable(xmlValue("scrollable", data)) end "space",
"scrollable"
})
return self return self
end, end,
} }
@@ -713,16 +1080,35 @@ return {
Graph = function(base, basalt) Graph = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local symbol, symbolCol = self:getGraphSymbol()
if (name == "maxEntries") then
self:setMaxEntries(value)
elseif (name == "type") then
self:setType(value)
elseif (name == "minValue") then
self:setMinValue(value)
elseif (name == "maxValue") then
self:setMaxValue(value)
elseif (name == "symbol") then
self:setGraphSymbol(value, symbolCol)
elseif (name == "symbolColor") then
self:setGraphSymbol(symbol, value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local symbol, symbolCol = self:getGraphSymbol() self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("maxEntries", data)~=nil)then self:setMaxEntries(xmlValue("maxEntries", data)) end "maxEntries",
if(xmlValue("type", data)~=nil)then self:setGraphType(xmlValue("type", data)) end "type",
if(xmlValue("minValue", data)~=nil)then self:setMinValue(xmlValue("minValue", data)) end "minValue",
if(xmlValue("maxValue", data)~=nil)then self:setMaxValue(xmlValue("maxValue", data)) end "maxValue",
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data) end "symbol",
if(xmlValue("symbolColor", data)~=nil)then symbolCol = xmlValue("symbolColor", data) end "symbolColor"
self:setGraphSymbol(symbol, symbolCol) })
if(data["item"]~=nil)then if(data["item"]~=nil)then
local tab = data["item"] local tab = data["item"]
if(tab.properties~=nil)then tab = {tab} end if(tab.properties~=nil)then tab = {tab} end
@@ -738,18 +1124,38 @@ return {
Treeview = function(base, basalt) Treeview = function(base, basalt)
local object = { local object = {
updateValue = function(self, name, value)
if (value == null) then return end
base.updateValue(self, name, value)
local selBg, selFg = self:getSelectionColor()
local xOffset, yOffset = self:getOffset()
if (name == "space") then
self:setSpace(value)
elseif (name == "scrollable") then
self:setScrollable(value)
elseif (name == "selectionBg") then
self:setSelectionColor(value, selFg)
elseif (name == "selectionFg") then
self:setSelectionColor(selBg, value)
elseif (name == "xOffset") then
self:setOffset(value, yOffset)
elseif (name == "yOffset") then
self:setOffset(xOffset, value)
end
end,
setValuesByXMLData = function(self, data, scripts) setValuesByXMLData = function(self, data, scripts)
base.setValuesByXMLData(self, data, scripts) base.setValuesByXMLData(self, data, scripts)
local selBg, selFg = self:getSelectionColor() local selBg, selFg = self:getSelectionColor()
local xOffset, yOffset = self:getOffset() local xOffset, yOffset = self:getOffset()
if(xmlValue("space", data)~=nil)then self:setSpace(xmlValue("space", data)) end self:updateSpecifiedValuesByXMLData(data, {
if(xmlValue("scrollable", data)~=nil)then self:setScrollable(xmlValue("scrollable", data)) end "space",
if(xmlValue("selectionBg", data)~=nil)then selBg = xmlValue("selectionBg", data) end "scrollable",
if(xmlValue("selectionFg", data)~=nil)then selFg = xmlValue("selectionFg", data) end "selectionBg",
self:setSelectionColor(selBg, selFg) "selectionFg",
if(xmlValue("xOffset", data)~=nil)then xOffset = xmlValue("xOffset", data) end "xOffset",
if(xmlValue("yOffset", data)~=nil)then yOffset = xmlValue("yOffset", data) end "yOffset"
self:setOffset(xOffset, yOffset) })
local function addNode(node, data) local function addNode(node, data)
if(data["node"]~=nil)then if(data["node"]~=nil)then
local tab = data["node"] local tab = data["node"]

View File

@@ -82,9 +82,9 @@ Here's an example of using the shared table to share data between two `<script>`
In this example, we first store a value in the shared table in one `<script>` tag, and then access that value in another `<script>` tag to update the titleLabel's text. In this example, we first store a value in the shared table in one `<script>` tag, and then access that value in another `<script>` tag to update the titleLabel's text.
You can also include Lua code directly within event attributes of UI elements. This allows you to execute specific actions or manipulate UI elements when certain events occur. You can also include Lua code directly within event properties of UI elements. This allows you to execute specific actions or manipulate UI elements when certain events occur.
To include Lua code in an event attribute, simply add the Lua code within the event attribute's value in the XML tag. The Lua code will be executed when the specified event is triggered. To include Lua code in an event property, simply add the Lua code within the event property's value in the XML tag. The Lua code will be executed when the specified event is triggered.
```xml ```xml
<label id="titleLabel" text="Welcome to Basalt!" x="10" y="2" /> <label id="titleLabel" text="Welcome to Basalt!" x="10" y="2" />
@@ -107,3 +107,22 @@ In both examples, you can see that XML provides a straightforward way to build a
Notably, you can access UI elements by their assigned ID directly in the event code. In the examples above, the titleLabel and okButton elements are accessed simply by referencing their IDs. This convenient feature eliminates the need to search for or store references to the elements in your code. Notably, you can access UI elements by their assigned ID directly in the event code. In the examples above, the titleLabel and okButton elements are accessed simply by referencing their IDs. This convenient feature eliminates the need to search for or store references to the elements in your code.
Remember: IDs have to be unique! Remember: IDs have to be unique!
## Reactive properties (BETA)
Most properties can also be set to track a shared variable using the curly braces {} syntax. In this case, the initial value for the variable should be set inside the `<script>` tag. When this variable is modified, the rendered value will be automatically updated.
The earlier example rewritten using reactive properties:
```xml
<label id="titleLabel" text="Welcome to Basalt!" x="10" y="2" />
<button id="okButton" text={shared.okButtonText} x="10" y="5">
<onClick>
shared.okButtonText = "Button clicked!"
</onClick>
</button>
<script>
shared.okButtonText = "OK"
</script>
```