From a97f799b4b671d7d1eaaa63e4ddc9f9186216875 Mon Sep 17 00:00:00 2001 From: Robert Jelic <36573031+NoryiE@users.noreply.github.com> Date: Fri, 31 Oct 2025 18:55:47 +0100 Subject: [PATCH] Fixed a issue with frame events Fixed Collection setItems not triggering render --- src/elements/BaseElement.lua | 11 +++---- src/elements/Collection.lua | 6 ++-- src/elements/Container.lua | 11 +++++-- src/elements/Frame.lua | 52 ++++++++++++++++++---------------- src/elements/VisualElement.lua | 2 +- 5 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/elements/BaseElement.lua b/src/elements/BaseElement.lua index fd003be..cd7738b 100644 --- a/src/elements/BaseElement.lua +++ b/src/elements/BaseElement.lua @@ -283,13 +283,13 @@ end function BaseElement:getActiveStates() local states = self.get("states") local result = {} - + for stateName, priority in pairs(states) do table.insert(result, {name = stateName, priority = priority}) end - + table.sort(result, function(a, b) return a.priority > b.priority end) - + return result end @@ -326,10 +326,11 @@ end --- @return table self The BaseElement instance function BaseElement:fireEvent(event, ...) if self.get("eventCallbacks")[event] then + local lastResult for _, callback in ipairs(self.get("eventCallbacks")[event]) do - local result = callback(self, ...) - return result + lastResult = callback(self, ...) end + return lastResult end return self end diff --git a/src/elements/Collection.lua b/src/elements/Collection.lua index 2b9ecf5..814e3b8 100644 --- a/src/elements/Collection.lua +++ b/src/elements/Collection.lua @@ -7,15 +7,15 @@ local CollectionEntry = require("libraries/collectionentry") local Collection = setmetatable({}, VisualElement) Collection.__index = Collection -Collection.defineProperty(Collection, "items", {default={}, type = "table"}) +Collection.defineProperty(Collection, "items", {default={}, type = "table", canTriggerRender = true}) ---@property selectable boolean true Whether items can be selected Collection.defineProperty(Collection, "selectable", {default = true, type = "boolean"}) ---@property multiSelection boolean false Whether multiple items can be selected at once Collection.defineProperty(Collection, "multiSelection", {default = false, type = "boolean"}) ---@property selectedBackground color blue Background color for selected items -Collection.defineProperty(Collection, "selectedBackground", {default = colors.blue, type = "color"}) +Collection.defineProperty(Collection, "selectedBackground", {default = colors.blue, type = "color", canTriggerRender = true}) ---@property selectedForeground color white Text color for selected items -Collection.defineProperty(Collection, "selectedForeground", {default = colors.white, type = "color"}) +Collection.defineProperty(Collection, "selectedForeground", {default = colors.white, type = "color", canTriggerRender = true}) ---@event onSelect {index number, item table} Fired when an item is selected diff --git a/src/elements/Container.lua b/src/elements/Container.lua index a2520d5..f42d67a 100644 --- a/src/elements/Container.lua +++ b/src/elements/Container.lua @@ -72,7 +72,7 @@ for k, _ in pairs(elementManager:getElementList()) do expect(1, self, "table") local element = self.basalt.create(k, ...) self:addChild(element) - element:postInit() + --element:postInit() return element end Container["addDelayed"..capitalizedName] = function(self, prop) @@ -294,7 +294,6 @@ function Container:unregisterChildEvent(child, eventName) end end self.set("childrenEventsSorted", false) - self:updateRender() break end end @@ -362,6 +361,12 @@ end --- @return boolean handled Whether the event was handled --- @return table? child The child that handled the event function Container:callChildrenEvent(visibleOnly, event, ...) + if visibleOnly and not self.get("childrenEventsSorted") then + for evt in pairs(self._values.childrenEvents) do + self:sortChildrenEvents(evt) + end + end + local children = visibleOnly and self.get("visibleChildrenEvents") or self.get("childrenEvents") if children[event] then local events = children[event] @@ -488,7 +493,7 @@ function Container:mouse_scroll(direction, x, y) if(VisualElement.mouse_scroll(self, direction, x, y))then local args = convertMousePosition(self, "mouse_scroll", direction, x, y) local success, child = self:callChildrenEvent(true, "mouse_scroll", table.unpack(args)) - return success + return true end return false end diff --git a/src/elements/Frame.lua b/src/elements/Frame.lua index 0d29f77..006e7a7 100644 --- a/src/elements/Frame.lua +++ b/src/elements/Frame.lua @@ -9,23 +9,16 @@ local Frame = setmetatable({}, Container) Frame.__index = Frame ---@property draggable boolean false Whether the frame is draggable -Frame.defineProperty(Frame, "draggable", {default = false, type = "boolean", setter=function(self, value) - if value then - self:listenEvent("mouse_click", true) - self:listenEvent("mouse_up", true) - self:listenEvent("mouse_drag", true) - end - return value -end}) +Frame.defineProperty(Frame, "draggable", {default = false, type = "boolean"}) ---@property draggingMap table {} The map of dragging positions Frame.defineProperty(Frame, "draggingMap", {default = {{x=1, y=1, width="width", height=1}}, type = "table"}) ---@property scrollable boolean false Whether the frame is scrollable -Frame.defineProperty(Frame, "scrollable", {default = false, type = "boolean", setter=function(self, value) - if value then - self:listenEvent("mouse_scroll", true) - end - return value -end}) +Frame.defineProperty(Frame, "scrollable", {default = false, type = "boolean"}) + +Frame.defineEvent(Frame, "mouse_click") +Frame.defineEvent(Frame, "mouse_drag") +Frame.defineEvent(Frame, "mouse_up") +Frame.defineEvent(Frame, "mouse_scroll") --- Creates a new Frame instance --- @shortDescription Creates a new Frame instance @@ -59,7 +52,7 @@ end --- @return boolean handled Whether the event was handled --- @protected function Frame:mouse_click(button, x, y) - if VisualElement.mouse_click(self, button, x, y) then + if self:isInBounds(x, y) then if self.get("draggable") then local relX, relY = self:getRelativePosition(x, y) local draggingMap = self.get("draggingMap") @@ -150,6 +143,17 @@ function Frame:getChildrenHeight() return maxHeight end +local function convertMousePosition(self, event, ...) + local args = {...} + if event and event:find("mouse_") then + local button, absX, absY = ... + local xOffset, yOffset = self.get("offsetX"), self.get("offsetY") + local relX, relY = self:getRelativePosition(absX + xOffset, absY + yOffset) + args = {button, relX, relY} + end + return args +end + --- @shortDescription Handles mouse scroll events --- @param direction number The scroll direction --- @param x number The x position of the scroll @@ -157,16 +161,15 @@ end --- @return boolean handled Whether the event was handled --- @protected function Frame:mouse_scroll(direction, x, y) - if Container.mouse_scroll(self, direction, x, y) then - return true - end + if(VisualElement.mouse_scroll(self, direction, x, y))then + local args = convertMousePosition(self, "mouse_scroll", direction, x, y) + local success, child = self:callChildrenEvent(true, "mouse_scroll", table.unpack(args)) + if success then + return true + end + if self.get("scrollable") then + local height = self.get("height") - if self.get("scrollable") then - local relX, relY = self:getRelativePosition(x, y) - local width = self.get("width") - local height = self.get("height") - - if relX >= 1 and relX <= width and relY >= 1 and relY <= height then local childrenHeight = self:getChildrenHeight() local currentOffset = self.get("offsetY") local maxScroll = math.max(0, childrenHeight - height) @@ -178,7 +181,6 @@ function Frame:mouse_scroll(direction, x, y) return true end end - return false end diff --git a/src/elements/VisualElement.lua b/src/elements/VisualElement.lua index fe0d830..de6b636 100644 --- a/src/elements/VisualElement.lua +++ b/src/elements/VisualElement.lua @@ -72,7 +72,7 @@ VisualElement.combineProperties(VisualElement, "size", "width", "height") VisualElement.combineProperties(VisualElement, "color", "foreground", "background") ---@event onClick {button string, x number, y number} Fired on mouse click ----@event onMouseUp {button, x, y} Fired on mouse button release +---@event onClickUp {button, x, y} Fired on mouse button release ---@event onRelease {button, x, y} Fired when mouse leaves while clicked ---@event onDrag {button, x, y} Fired when mouse moves while clicked ---@event onScroll {direction, x, y} Fired on mouse scroll