From aa0ebde8b31d11953eed52224135a3b105c06664 Mon Sep 17 00:00:00 2001 From: Sabine Lim Date: Thu, 18 May 2023 01:58:17 +1000 Subject: [PATCH 1/2] Allow events to be registered on elements without parents --- Basalt/objects/Container.lua | 4 ++++ Basalt/objects/Object.lua | 22 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Basalt/objects/Container.lua b/Basalt/objects/Container.lua index 055ec75..7cfe484 100644 --- a/Basalt/objects/Container.lua +++ b/Basalt/objects/Container.lua @@ -59,6 +59,9 @@ return function(name, basalt) table.insert(elements, {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 @@ -96,6 +99,7 @@ return function(name, basalt) return true end end + self:removeEvents(element) sorted = false end diff --git a/Basalt/objects/Object.lua b/Basalt/objects/Object.lua index ca27977..3a96666 100644 --- a/Basalt/objects/Object.lua +++ b/Basalt/objects/Object.lua @@ -13,6 +13,7 @@ return function(name, basalt) local isEnabled,initialized = true,false local eventSystem = basaltEvent() + local registeredEvents = {} local activeEvents = {} local parent @@ -113,7 +114,6 @@ return function(name, basalt) remove = function(self) if (parent ~= nil) then parent:removeObject(self) - parent:removeEvents(self) end self:updateDraw() return self @@ -139,11 +139,19 @@ return function(name, basalt) return eventSystem end, + getRegisteredEvents = function(self) + return registeredEvents + end, + registerEvent = function(self, event, func) if(parent~=nil)then parent:addEvent(event, self) end - return eventSystem:registerEvent(event, func) + eventSystem:registerEvent(event, func) + if (registeredEvents[event] == nil) then + registeredEvents[event] = {} + end + table.insert(registeredEvents[event], func) end, removeEvent = function(self, event, index) @@ -152,7 +160,13 @@ return function(name, basalt) parent:removeEvent(event, self) end end - return eventSystem:removeEvent(event, index) + eventSystem:removeEvent(event, index) + if (registeredEvents[event] ~= nil) then + table.remove(registeredEvents[event], index) + if (#registeredEvents[event] == 0) then + registeredEvents[event] = nil + end + end end, eventHandler = function(self, event, ...) @@ -262,7 +276,7 @@ return function(name, basalt) end return self end, - } + } object.__index = object return object -- 2.49.1 From e60493a0393efcec63b4f50aa40e51b1646d7675 Mon Sep 17 00:00:00 2001 From: Sabine Lim Date: Thu, 18 May 2023 02:26:26 +1000 Subject: [PATCH 2/2] Fix addObject --- Basalt/main.lua | 13 +- Basalt/objects/BaseFrame.lua | 8 +- Basalt/objects/Container.lua | 194 ++++++++++++++++------------- Basalt/objects/Flexbox.lua | 20 +-- Basalt/objects/Frame.lua | 8 +- Basalt/objects/Input.lua | 4 +- Basalt/objects/Object.lua | 4 +- Basalt/objects/ScrollableFrame.lua | 12 +- Basalt/objects/VisualObject.lua | 10 +- 9 files changed, 148 insertions(+), 125 deletions(-) diff --git a/Basalt/main.lua b/Basalt/main.lua index fb36059..d30b721 100644 --- a/Basalt/main.lua +++ b/Basalt/main.lua @@ -74,12 +74,12 @@ local getObjects = function() return moddedObjects end -local getObject = function(id) - return getObjects()[id] +local getObject = function(objectName) + return getObjects()[objectName] end -local createObject = function(self, objectName, id) - return getObject(objectName)(id, self) +local createObject = function(basalt, objectName, id) + return getObject(objectName)(id, basalt) end local bInstance = { @@ -437,6 +437,11 @@ basalt = { setVariable = setVariable, getVariable = getVariable, + getObjects = getObjects, + getObject = getObject, + + createObject = createObject, + setBaseTerm = function(_baseTerm) baseTerm = _baseTerm end, diff --git a/Basalt/objects/BaseFrame.lua b/Basalt/objects/BaseFrame.lua index 9e46b10..dc0f0ac 100644 --- a/Basalt/objects/BaseFrame.lua +++ b/Basalt/objects/BaseFrame.lua @@ -120,10 +120,10 @@ return function(name, basalt) if(self:isVisible())then if(updateRender)then base.render(self) - local objects = self:getObjects() - for _, obj in ipairs(objects) do - if (obj.element.render ~= nil) then - obj.element:render() + local children = self:getChildren() + for _, child in ipairs(children) do + if (child.element.render ~= nil) then + child.element:render() end end updateRender = false diff --git a/Basalt/objects/Container.lua b/Basalt/objects/Container.lua index 7cfe484..5194faf 100644 --- a/Basalt/objects/Container.lua +++ b/Basalt/objects/Container.lua @@ -5,13 +5,13 @@ return function(name, basalt) local base = basalt.getObject("VisualObject")(name, basalt) local objectType = "Container" - local elements = {} + local children = {} local events = {} local container = {} - local focusedObject + local focusedChild local sorted = true local objId, evId = 0, 0 @@ -30,48 +30,82 @@ return function(name, basalt) end end - local function getObject(self, name) - if(type(name)=="table")then name = name:getName() end - for i, v in ipairs(elements) do - if v.element:getName() == name then - return v.element - end - end + local function getChildren(self) + self:sortChildren() + return children end - local function getDeepObject(self, name) - local o = getObject(name) - if(o~=nil)then return o end - for _, value in pairs(objects) do - if (b:getType() == "Container") then - local oF = b:getDeepObject(name) - if(oF~=nil)then return oF 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 addObject(self, element, el2) - if (getObject(element:getName()) ~= nil) then + 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(elements, {element = element, zIndex = zIndex, objId = objId}) + 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 + 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 updateZIndex(self, element, newZ) objId = objId + 1 evId = evId + 1 - for _,v in pairs(elements)do + for _,v in pairs(children)do if(v.element==element)then v.zIndex = newZ v.objId = objId @@ -90,19 +124,6 @@ return function(name, basalt) self:updateDraw() end - local function removeObject(self, element) - if(type(element)=="string")then element = getObject(element:getName()) end - if(element==nil)then return end - for i, v in ipairs(elements) do - if v.element == element then - table.remove(elements, i) - return true - end - end - self:removeEvents(element) - sorted = false - end - local function removeEvents(self, element) local parent = self:getParent() for a, b in pairs(events) do @@ -158,11 +179,6 @@ return function(name, basalt) sorted = false end - local function getObjects(self) - self:sortElementOrder() - return elements - end - local function getEvents(self, event) return event~=nil and events[event] or events end @@ -192,24 +208,24 @@ return function(name, basalt) return self end, - searchObjects = function(self, name) - local t = {} - for k,v in pairs(elements)do - if(string.find(k:getName(), name))then - table.insert(t, v) + 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 t + return results end, - getObjectsByType = function(self, t) - local t = {} - for k,v in pairs(elements)do - if(v:isType(t))then - table.insert(t, v) + 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 t + return results end, setImportant = function(self, element) @@ -225,11 +241,11 @@ return function(name, basalt) end end end - for i, v in ipairs(elements) do + for i, v in ipairs(children) do if v.element == element then v.objId = objId - table.remove(elements, i) - table.insert(elements, v) + table.remove(children, i) + table.insert(children, v) break end end @@ -239,52 +255,54 @@ return function(name, basalt) sorted = false end, - sortElementOrder = function(self) - if(sorted)then return end - table.sort(elements, objSort) - for a, b in pairs(events) do - table.sort(events[a], evSort) + 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, - removeFocusedObject = function(self) - if(focusedObject~=nil)then - if(getObject(self, focusedObject)~=nil)then - focusedObject:loseFocusHandler() + clearFocusedChild = function(self) + if(focusedChild~=nil)then + if(getChild(self, focusedChild)~=nil)then + focusedChild:loseFocusHandler() end end - focusedObject = nil + focusedChild = nil return self end, - setFocusedObject = function(self, obj) - if(focusedObject~=obj)then - if(focusedObject~=nil)then - if(getObject(self, focusedObject)~=nil)then - focusedObject:loseFocusHandler() + 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(getObject(self, obj)~=nil)then + if(getChild(self, obj)~=nil)then obj:getFocusHandler() end end - focusedObject = obj + focusedChild = obj return true end return false end, - getFocusedObject = function(self) - return focusedObject + getFocused = function(self) + return focusedChild end, - getObject = getObject, - getObjects = getObjects, - getDeepObject = getDeepObject, - addObject = addObject, - removeObject = removeObject, + getChild = getChild, + getChildren = getChildren, + getDeepChildren = getDeepChild, + addChild = addChild, + removeChild = removeChild, getEvents = getEvents, getEvent = getEvent, addEvent = addEvent, @@ -300,7 +318,7 @@ return function(name, basalt) customEventHandler = function(self, ...) base.customEventHandler(self, ...) - for _, o in pairs(elements) do + for _, o in pairs(children) do if (o.element.customEventHandler ~= nil) then o.element:customEventHandler(...) end @@ -309,7 +327,7 @@ return function(name, basalt) loseFocusHandler = function(self) base.loseFocusHandler(self) - if(focusedObject~=nil)then focusedObject:loseFocusHandler() focusedObject = nil end + if(focusedChild~=nil)then focusedChild:loseFocusHandler() focusedChild = nil end end, getBasalt = function(self) @@ -326,7 +344,7 @@ return function(name, basalt) if(base.eventHandler~=nil)then base.eventHandler(self, ...) if(events["other_event"]~=nil)then - self:sortElementOrder() + self:sortChildren() for _, obj in ipairs(events["other_event"]) do if (obj.element.eventHandler ~= nil) then obj.element.eventHandler(obj.element, ...) @@ -342,7 +360,7 @@ return function(name, basalt) if(base[v[1]]~=nil)then if(base[v[1]](self, btn, x, y, ...))then if(events[k]~=nil)then - self:sortElementOrder() + self:sortChildren() for _, obj in ipairs(events[k]) do if (obj.element[v[1]] ~= nil) then local xO, yO = 0, 0 @@ -360,7 +378,7 @@ return function(name, basalt) end end if(v[2])then - self:removeFocusedObject() + self:clearFocusedChild() end end return true @@ -373,8 +391,8 @@ return function(name, basalt) container[v] = function(self, ...) if(base[v]~=nil)then if(base[v](self, ...))then - if(events[k]~=nil)then - self:sortElementOrder() + 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 @@ -390,7 +408,7 @@ return function(name, basalt) for objectName, _ in pairs(basalt.getObjects()) do container["add" .. objectName] = function(self, id) - return addObject(self, basalt:createObject(objectName, id)) + return self:addChild(basalt:createObject(objectName, id)) end end diff --git a/Basalt/objects/Flexbox.lua b/Basalt/objects/Flexbox.lua index c7f0b95..8411266 100644 --- a/Basalt/objects/Flexbox.lua +++ b/Basalt/objects/Flexbox.lua @@ -21,12 +21,12 @@ return function(name, basalt) end local function applyLayout(self) - local objects = self:getObjects() - local totalElements = #objects + local children = self:getChildren() + local totalChildren = #children local width, height = self:getSize() - + local mainAxisTotalChildSize = 0 - for _, obj in ipairs(objects) do + for _, obj in ipairs(children) do local objWidth, objHeight = obj.element:getSize() if flexDirection == "row" then mainAxisTotalChildSize = mainAxisTotalChildSize + objWidth @@ -34,15 +34,15 @@ return function(name, basalt) mainAxisTotalChildSize = mainAxisTotalChildSize + objHeight end end - local mainAxisAvailableSpace = (flexDirection == "row" and width or height) - mainAxisTotalChildSize - (spacing * (totalElements - 1)) + local mainAxisAvailableSpace = (flexDirection == "row" and width or height) - mainAxisTotalChildSize - (spacing * (totalChildren - 1)) local justifyContentOffset = 1 if justifyContent == "center" then justifyContentOffset = 1 + mainAxisAvailableSpace / 2 elseif justifyContent == "flex-end" then - justifyContentOffset = 1 + mainAxisvailableSpace + justifyContentOffset = 1 + mainAxisAvailableSpace end - - for _, obj in ipairs(objects) do + + for _, obj in ipairs(children) do local alignItemsOffset = getObjectOffAxisOffset(self, obj) if flexDirection == "row" then obj.element:setPosition(justifyContentOffset, alignItemsOffset) @@ -55,7 +55,7 @@ return function(name, basalt) end end end - + local object = { getType = function() @@ -71,7 +71,7 @@ return function(name, basalt) applyLayout(self) return self end, - + getSpacing = function(self) return spacing end, diff --git a/Basalt/objects/Frame.lua b/Basalt/objects/Frame.lua index 838e15a..472f488 100644 --- a/Basalt/objects/Frame.lua +++ b/Basalt/objects/Frame.lua @@ -64,10 +64,10 @@ return function(name, basalt) if(base.render~=nil)then if(self:isVisible())then base.render(self) - local objects = self:getObjects() - for _, obj in ipairs(objects) do - if (obj.element.render ~= nil) then - obj.element:render() + local children = self:getChildren() + for _, child in ipairs(children) do + if (child.element.render ~= nil) then + child.element:render() end end end diff --git a/Basalt/objects/Input.lua b/Basalt/objects/Input.lua index 7e41d43..2355ac3 100644 --- a/Basalt/objects/Input.lua +++ b/Basalt/objects/Input.lua @@ -162,7 +162,7 @@ return function(name, basalt) end end if (key == keys.enter) then - parent:removeFocusedObject(self) + parent:clearFocusedChild(self) end if (key == keys.right) then local tLength = tostring(base.getValue()):len() @@ -263,7 +263,7 @@ return function(name, basalt) end end local parent = self:getParent() - parent:removeFocusedObject() + parent:clearFocusedChild() end end, diff --git a/Basalt/objects/Object.lua b/Basalt/objects/Object.lua index 3a96666..a0d1529 100644 --- a/Basalt/objects/Object.lua +++ b/Basalt/objects/Object.lua @@ -61,7 +61,7 @@ return function(name, basalt) if(noRemove)then parent = newParent return self end if (newParent.getType ~= nil and newParent:isType("Container")) then self:remove() - newParent:addObject(self) + newParent:addChild(self) if (self.show) then self:show() end @@ -113,7 +113,7 @@ return function(name, basalt) remove = function(self) if (parent ~= nil) then - parent:removeObject(self) + parent:removeChild(self) end self:updateDraw() return self diff --git a/Basalt/objects/ScrollableFrame.lua b/Basalt/objects/ScrollableFrame.lua index b4aa1d3..d138b38 100644 --- a/Basalt/objects/ScrollableFrame.lua +++ b/Basalt/objects/ScrollableFrame.lua @@ -11,8 +11,8 @@ return function(name, basalt) local function getHorizontalScrollAmount(self) local amount = 0 - local objects = self:getObjects() - for _, b in pairs(objects) do + local children = self:getChildren() + for _, b in pairs(children) do if(b.element.getWidth~=nil)and(b.element.getX~=nil)then local w, x = b.element:getWidth(), b.element:getX() local width = self:getWidth() @@ -35,8 +35,8 @@ return function(name, basalt) local function getVerticalScrollAmount(self) local amount = 0 - local objects = self:getObjects() - for _, b in pairs(objects) do + local children = self:getChildren() + for _, b in pairs(children) do if(b.element.getHeight~=nil)and(b.element.getY~=nil)then local h, y = b.element:getHeight(), b.element:getY() local height = self:getHeight() @@ -106,7 +106,7 @@ return function(name, basalt) scrollHandler = function(self, dir, x, y) if(base:getBase().scrollHandler(self, dir, x, y))then - self:sortElementOrder() + self:sortChildren() for _, obj in ipairs(self:getEvents("mouse_scroll")) do if (obj.element.scrollHandler ~= nil) then local xO, yO = 0, 0 @@ -122,7 +122,7 @@ return function(name, basalt) end end scrollHandler(self, dir, x, y) - self:removeFocusedObject() + self:clearFocusedChild() return true end end, diff --git a/Basalt/objects/VisualObject.lua b/Basalt/objects/VisualObject.lua index bac7ba7..1fad765 100644 --- a/Basalt/objects/VisualObject.lua +++ b/Basalt/objects/VisualObject.lua @@ -3,7 +3,7 @@ local tHex = require("tHex") local sub, find, insert = string.sub, string.find, table.insert -return function(name, basalt) +return function(name, basalt) local base = basalt.getObject("Object")(name, basalt) -- Base object local objectType = "VisualObject" -- not changeable @@ -94,7 +94,7 @@ return function(name, basalt) setFocus = function(self) if (parent ~= nil) then - parent:setFocusedObject(self) + parent:setFocusedChild(self) end return self end, @@ -312,7 +312,7 @@ return function(name, basalt) local val = self:sendEvent("mouse_click", button, x - (objX-1), y - (objY-1), x, y, isMon) if(val==false)then return false end if(parent~=nil)then - parent:setFocusedObject(self) + parent:setFocusedChild(self) end isClicked = true isDragging = true @@ -343,7 +343,7 @@ return function(name, basalt) dragStartX, dragStartY = x, y if(val~=nil)then return val end if(parent~=nil)then - parent:setFocusedObject(self) + parent:setFocusedChild(self) end return true end @@ -361,7 +361,7 @@ return function(name, basalt) local val = self:sendEvent("mouse_scroll", dir, x - (objX-1), y - (objY-1)) if(val==false)then return false end if(parent~=nil)then - parent:setFocusedObject(self) + parent:setFocusedChild(self) end return true end -- 2.49.1