429 lines
13 KiB
Lua
429 lines
13 KiB
Lua
local utils = require("utils")
|
|
local tableCount = utils.tableCount
|
|
|
|
return function(name, basalt)
|
|
local base = basalt.getObject("VisualObject")(name, basalt)
|
|
local objectType = "Container"
|
|
|
|
local children = {}
|
|
|
|
local events = {}
|
|
|
|
local container = {}
|
|
|
|
local focusedChild
|
|
local sorted = true
|
|
local objId, evId = 0, 0
|
|
|
|
local objSort = function(a, b)
|
|
if a.zIndex == b.zIndex then
|
|
return a.objId < b.objId
|
|
else
|
|
return a.zIndex < b.zIndex
|
|
end
|
|
end
|
|
local evSort = function(a, b)
|
|
if a.zIndex == b.zIndex then
|
|
return a.evId > b.evId
|
|
else
|
|
return a.zIndex > b.zIndex
|
|
end
|
|
end
|
|
|
|
local function getChildren(self)
|
|
self:sortChildren()
|
|
return children
|
|
end
|
|
|
|
local function getChild(self, name)
|
|
if (type(name)=="table") then
|
|
name = name:getName()
|
|
end
|
|
for _, v in ipairs(children) do
|
|
if v.element:getName() == name then
|
|
return v.element
|
|
end
|
|
end
|
|
end
|
|
|
|
local function getDeepChild(self, name)
|
|
local maybeChild = getChild(name)
|
|
if (maybeChild ~= nil) then
|
|
return maybeChild
|
|
end
|
|
for _, child in ipairs(children) do
|
|
if (child:getType() == "Container") then
|
|
local maybeDeepChild = child:getDeepChild(name)
|
|
if (maybeDeepChild ~= nil) then
|
|
return maybeDeepChild
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function addChild(self, element)
|
|
if (getChild(element:getName()) ~= nil) then
|
|
return
|
|
end
|
|
objId = objId + 1
|
|
local zIndex = element:getZIndex()
|
|
table.insert(children, {element = element, zIndex = zIndex, objId = objId})
|
|
sorted = false
|
|
element:setParent(self, true)
|
|
for event, _ in pairs(element:getRegisteredEvents()) do
|
|
self:addEvent(event, element)
|
|
end
|
|
if (element.init~=nil) then
|
|
element:init()
|
|
end
|
|
if (element.load~=nil) then
|
|
element:load()
|
|
end
|
|
if (element.draw~=nil) then
|
|
element:draw()
|
|
end
|
|
return element
|
|
end
|
|
|
|
local function removeChild(self, element)
|
|
if (type(element)=="string") then
|
|
element = getChild(element:getName())
|
|
end
|
|
if (element==nil) then
|
|
return
|
|
end
|
|
for i, v in ipairs(children) do
|
|
if v.element == element then
|
|
table.remove(children, i)
|
|
return true
|
|
end
|
|
end
|
|
self:removeEvents(element)
|
|
sorted = false
|
|
end
|
|
|
|
local function removeChildren(self)
|
|
local parent = self:getParent()
|
|
children = {}
|
|
events = {}
|
|
sorted = false
|
|
objId = 0
|
|
evId = 0
|
|
focusedChild = nil
|
|
parent:removeEvents(self)
|
|
end
|
|
|
|
local function updateZIndex(self, element, newZ)
|
|
objId = objId + 1
|
|
evId = evId + 1
|
|
for _,v in pairs(children)do
|
|
if(v.element==element)then
|
|
v.zIndex = newZ
|
|
v.objId = objId
|
|
break
|
|
end
|
|
end
|
|
for _,v in pairs(events)do
|
|
for a,b in pairs(v)do
|
|
if(b.element==element)then
|
|
b.zIndex = newZ
|
|
b.evId = evId
|
|
end
|
|
end
|
|
end
|
|
sorted = false
|
|
self:updateDraw()
|
|
end
|
|
|
|
local function removeEvents(self, element)
|
|
local parent = self:getParent()
|
|
for a, b in pairs(events) do
|
|
for c, d in pairs(b) do
|
|
if(d.element == element)then
|
|
table.remove(events[a], c)
|
|
end
|
|
end
|
|
if(tableCount(events[a])<=0)then
|
|
if(parent~=nil)then
|
|
parent:removeEvent(a, self)
|
|
end
|
|
end
|
|
end
|
|
sorted = false
|
|
end
|
|
|
|
local function getEvent(self, event, name)
|
|
if(type(name)=="table")then name = name:getName() end
|
|
if(events[event]~=nil)then
|
|
for _, obj in pairs(events[event]) do
|
|
if (obj.element:getName() == name) then
|
|
return obj
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function addEvent(self, event, element)
|
|
if (getEvent(self, event, element:getName()) ~= nil) then
|
|
return
|
|
end
|
|
local zIndex = element:getZIndex()
|
|
evId = evId + 1
|
|
if(events[event]==nil)then events[event] = {} end
|
|
table.insert(events[event], {element = element, zIndex = zIndex, evId = evId})
|
|
sorted = false
|
|
self:listenEvent(event)
|
|
return element
|
|
end
|
|
|
|
local function removeEvent(self, event, element)
|
|
if(events[event]~=nil)then
|
|
for a, b in pairs(events[event]) do
|
|
if(b.element == element)then
|
|
table.remove(events[event], a)
|
|
end
|
|
end
|
|
if(tableCount(events[event])<=0)then
|
|
self:listenEvent(event, false)
|
|
end
|
|
end
|
|
sorted = false
|
|
end
|
|
|
|
local function getEvents(self, event)
|
|
return event~=nil and events[event] or events
|
|
end
|
|
|
|
container = {
|
|
getType = function()
|
|
return objectType
|
|
end,
|
|
|
|
getBase = function(self)
|
|
return base
|
|
end,
|
|
|
|
isType = function(self, t)
|
|
return objectType==t or base.isType~=nil and base.isType(t) or false
|
|
end,
|
|
|
|
setSize = function(self, ...)
|
|
base.setSize(self, ...)
|
|
self:customEventHandler("basalt_FrameResize")
|
|
return self
|
|
end,
|
|
|
|
setPosition = function(self, ...)
|
|
base.setPosition(self, ...)
|
|
self:customEventHandler("basalt_FrameReposition")
|
|
return self
|
|
end,
|
|
|
|
searchChildren = function(self, name)
|
|
local results = {}
|
|
for _, child in pairs(children) do
|
|
if (string.find(child.element:getName(), name)) then
|
|
table.insert(results, child)
|
|
end
|
|
end
|
|
return results
|
|
end,
|
|
|
|
getChildrenByType = function(self, type)
|
|
local results = {}
|
|
for _, child in pairs(children) do
|
|
if (child.element:isType(type)) then
|
|
table.insert(results, child)
|
|
end
|
|
end
|
|
return results
|
|
end,
|
|
|
|
setImportant = function(self, element)
|
|
objId = objId + 1
|
|
evId = evId + 1
|
|
for a, b in pairs(events) do
|
|
for c, d in pairs(b) do
|
|
if(d.element == element)then
|
|
d.evId = evId
|
|
table.remove(events[a], c)
|
|
table.insert(events[a], d)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
for i, v in ipairs(children) do
|
|
if v.element == element then
|
|
v.objId = objId
|
|
table.remove(children, i)
|
|
table.insert(children, v)
|
|
break
|
|
end
|
|
end
|
|
if(self.updateDraw~=nil)then
|
|
self:updateDraw()
|
|
end
|
|
sorted = false
|
|
end,
|
|
|
|
sortChildren = function(self)
|
|
if (sorted) then
|
|
return
|
|
end
|
|
table.sort(children, objSort)
|
|
for event, _ in pairs(events) do
|
|
table.sort(events[event], evSort)
|
|
end
|
|
sorted = true
|
|
end,
|
|
|
|
clearFocusedChild = function(self)
|
|
if(focusedChild~=nil)then
|
|
if(getChild(self, focusedChild)~=nil)then
|
|
focusedChild:loseFocusHandler()
|
|
end
|
|
end
|
|
focusedChild = nil
|
|
return self
|
|
end,
|
|
|
|
setFocusedChild = function(self, obj)
|
|
if(focusedChild~=obj)then
|
|
if(focusedChild~=nil)then
|
|
if(getChild(self, focusedChild)~=nil)then
|
|
focusedChild:loseFocusHandler()
|
|
end
|
|
end
|
|
if(obj~=nil)then
|
|
if(getChild(self, obj)~=nil)then
|
|
obj:getFocusHandler()
|
|
end
|
|
end
|
|
focusedChild = obj
|
|
return true
|
|
end
|
|
return false
|
|
end,
|
|
|
|
getFocused = function(self)
|
|
return focusedChild
|
|
end,
|
|
|
|
getChild = getChild,
|
|
getChildren = getChildren,
|
|
getDeepChildren = getDeepChild,
|
|
addChild = addChild,
|
|
removeChild = removeChild,
|
|
removeChildren = removeChildren,
|
|
getEvents = getEvents,
|
|
getEvent = getEvent,
|
|
addEvent = addEvent,
|
|
removeEvent = removeEvent,
|
|
removeEvents = removeEvents,
|
|
updateZIndex = updateZIndex,
|
|
|
|
listenEvent = function(self, event, active)
|
|
base.listenEvent(self, event, active)
|
|
if(events[event]==nil)then events[event] = {} end
|
|
return self
|
|
end,
|
|
|
|
customEventHandler = function(self, ...)
|
|
base.customEventHandler(self, ...)
|
|
for _, o in pairs(children) do
|
|
if (o.element.customEventHandler ~= nil) then
|
|
o.element:customEventHandler(...)
|
|
end
|
|
end
|
|
end,
|
|
|
|
loseFocusHandler = function(self)
|
|
base.loseFocusHandler(self)
|
|
if(focusedChild~=nil)then focusedChild:loseFocusHandler() focusedChild = nil end
|
|
end,
|
|
|
|
getBasalt = function(self)
|
|
return basalt
|
|
end,
|
|
|
|
setPalette = function(self, col, ...)
|
|
local parent = self:getParent()
|
|
parent:setPalette(col, ...)
|
|
return self
|
|
end,
|
|
|
|
eventHandler = function(self, ...)
|
|
if(base.eventHandler~=nil)then
|
|
base.eventHandler(self, ...)
|
|
if(events["other_event"]~=nil)then
|
|
self:sortChildren()
|
|
for _, obj in ipairs(events["other_event"]) do
|
|
if (obj.element.eventHandler ~= nil) then
|
|
obj.element.eventHandler(obj.element, ...)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
}
|
|
|
|
for k,v in pairs({mouse_click={"mouseHandler", true},mouse_up={"mouseUpHandler", false},mouse_drag={"dragHandler", false},mouse_scroll={"scrollHandler", true},mouse_hover={"hoverHandler", false}})do
|
|
container[v[1]] = function(self, btn, x, y, ...)
|
|
if(base[v[1]]~=nil)then
|
|
if(base[v[1]](self, btn, x, y, ...))then
|
|
if(events[k]~=nil)then
|
|
self:sortChildren()
|
|
for _, obj in ipairs(events[k]) do
|
|
if (obj.element[v[1]] ~= nil) then
|
|
local xO, yO = 0, 0
|
|
if(self.getOffset~=nil)then
|
|
xO, yO = self:getOffset()
|
|
end
|
|
if(obj.element.getIgnoreOffset~=nil)then
|
|
if(obj.element.getIgnoreOffset())then
|
|
xO, yO = 0, 0
|
|
end
|
|
end
|
|
if (obj.element[v[1]](obj.element, btn, x+xO, y+yO, ...)) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
if(v[2])then
|
|
self:clearFocusedChild()
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for k,v in pairs({key="keyHandler",key_up="keyUpHandler",char="charHandler"})do
|
|
container[v] = function(self, ...)
|
|
if(base[v]~=nil)then
|
|
if(base[v](self, ...))then
|
|
if(events[k]~=nil)then
|
|
self:sortChildren()
|
|
for _, obj in ipairs(events[k]) do
|
|
if (obj.element[v] ~= nil) then
|
|
if (obj.element[v](obj.element, ...)) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for objectName, _ in pairs(basalt.getObjects()) do
|
|
container["add" .. objectName] = function(self, id)
|
|
return self:addChild(basalt:createObject(objectName, id))
|
|
end
|
|
end
|
|
|
|
container.__index = container
|
|
return setmetatable(container, base)
|
|
end |