From be0771d0d3eb433adc63159881d3676966d699d8 Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Tue, 11 Nov 2025 13:13:22 -0500 Subject: [PATCH] callback renamed -> onEvent --- FlexLove.lua | 4 +-- README.md | 25 ++++++++++---- examples/03_theming_system.lua | 8 ++--- examples/05_animations.lua | 6 ++-- examples/06_event_system.lua | 12 +++---- examples/11_input_controls.lua | 6 ++-- examples/12_z_index_layering.lua | 2 +- examples/13_comprehensive_demo.lua | 2 +- examples/14_drag_slider.lua | 2 +- modules/Element.lua | 38 ++++++++++----------- modules/GuiState.lua | 4 +-- modules/StateManager.lua | 2 +- modules/utils.lua | 2 +- testing/__tests__/16_event_system_tests.lua | 20 +++++------ testing/__tests__/29_drag_event_tests.lua | 16 ++++----- 15 files changed, 80 insertions(+), 69 deletions(-) diff --git a/FlexLove.lua b/FlexLove.lua index 62f1708..f590cca 100644 --- a/FlexLove.lua +++ b/FlexLove.lua @@ -384,8 +384,8 @@ function Gui.getElementAtPosition(x, y) local adjustedY = y + scrollOffsetY if adjustedX >= bx and adjustedX <= bx + bw and adjustedY >= by and adjustedY <= by + bh then - -- Collect interactive elements (those with callbacks) - if element.callback and not element.disabled then + -- Collect interactive elements (those with onEvent handlers) + if element.onEvent and not element.disabled then table.insert(candidates, element) end diff --git a/README.md b/README.md index ec50423..e4205fe 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ local button = FlexLove.Element.new({ text = "Click Me", textSize = "md", themeComponent = "button", - callback = function(element, event) + onEvent = function(element, event) print("Button clicked!") end }) @@ -105,14 +105,25 @@ local someGameState = true local button1 = FlexLove.Element.new({ text = "Button 1", disabled = someGameState, - callback = function() print("Clicked!") end + onEvent = function() print("Clicked!") end }) -- ... other things ... -- local someGameState = false -- button1 will not change its disabled state, you need a way to update the element local button2 = FlexLove.Element.new({ text = "Click to activate button 1", - callback = function(_, event) + onEvent = function(_, event) + if event.type == "release" then -- only fire on mouse release + button1.disabled = false -- this will actual update the element + end + end +}) +-- ... other things ... -- +local someGameState = false -- button1 will not change its disabled state, you need a way to update the element + +local button2 = FlexLove.Element.new({ + text = "Click to activate button 1", + onEvent = function(_, event) if event.type == "release" then -- only fire on mouse release button1.disabled = false -- this will actual update the element end @@ -137,14 +148,14 @@ local someGameState = true local button1 = FlexLove.Element.new({ text = "Button 1", disabled = someGameState, - callback = function() print("Clicked!") end + onEvent = function() print("Clicked!") end }) -- ... other things ... -- local someGameState = false -- button1 in immediate mode will have its state updated local button2 = FlexLove.Element.new({ text = "Click to activate button 1", - callback = function(_, event) + onEvent = function(_, event) if event.type == "release" then -- only fire on mouse release button1.disabled = false -- this will also update the element end @@ -211,7 +222,7 @@ Common properties for all elements: themeComponent = "button", -- Component type from theme -- Interaction - callback = function(element, event) end, + onEvent = function(element, event) end, disabled = false, disableHighlight = false, -- Disable pressed overlay (auto-true for themed elements) @@ -351,7 +362,7 @@ Themes support state-based rendering: Enhanced event handling with detailed event information: ```lua -callback = function(element, event) +onEvent = function(element, event) -- event.type: "click", "press", "release", "rightclick", "middleclick" -- event.button: 1 (left), 2 (right), 3 (middle) -- event.x, event.y: Mouse position diff --git a/examples/03_theming_system.lua b/examples/03_theming_system.lua index a40b168..8b9b3a2 100644 --- a/examples/03_theming_system.lua +++ b/examples/03_theming_system.lua @@ -119,7 +119,7 @@ function Lv.load() textSize = "2vh", textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then print("Normal button clicked!") end @@ -139,7 +139,7 @@ function Lv.load() textColor = Color.new(0.3, 1, 0.3, 1), textAlign = enums.TextAlign.CENTER, active = true, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then element.active = not element.active print("Active button toggled:", element.active) @@ -160,7 +160,7 @@ function Lv.load() textColor = Color.new(0.5, 0.5, 0.5, 1), textAlign = enums.TextAlign.CENTER, disabled = true, - callback = function(element, event) + onEvent = function(element, event) -- This won't be called because button is disabled print("This shouldn't print!") end, @@ -179,7 +179,7 @@ function Lv.load() textSize = "2vh", textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then clickCount = clickCount + 1 element.text = "Click Me! (" .. clickCount .. ")" diff --git a/examples/05_animations.lua b/examples/05_animations.lua index 16d057c..2b17350 100644 --- a/examples/05_animations.lua +++ b/examples/05_animations.lua @@ -63,7 +63,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 10, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then -- Fade out then fade in local fadeOut = Animation.fade(1.0, 1.0, 0.0) @@ -109,7 +109,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 10, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then -- Scale up local scaleUp = Animation.scale( @@ -193,7 +193,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 8, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then -- Fade out and in with this easing local fadeOut = Animation.fade(0.8, 1.0, 0.2) diff --git a/examples/06_event_system.lua b/examples/06_event_system.lua index 4c499ce..dc80a4b 100644 --- a/examples/06_event_system.lua +++ b/examples/06_event_system.lua @@ -71,7 +71,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 10, - callback = function(element, event) + onEvent = function(element, event) local buttonName = event.button == 1 and "Left" or (event.button == 2 and "Right" or "Middle") local eventTypeName = event.type:sub(1,1):upper() .. event.type:sub(2) @@ -113,7 +113,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 10, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then local mods = {} if event.modifiers.shift then table.insert(mods, "Shift") end @@ -152,7 +152,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 10, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then if event.clickCount == 1 then addLogEntry("Single click detected") @@ -237,7 +237,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 5, - callback = function(element, event) + onEvent = function(element, event) if event.type == "press" then addLogEntry("Button 1: PRESSED") element.backgroundColor = Color.new(0.2, 0.3, 0.6, 1) @@ -259,7 +259,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 5, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then clickCounter = clickCounter + 1 element.text = "Click Counter: " .. clickCounter @@ -278,7 +278,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 5, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then eventLog = {} addLogEntry("Log cleared!") diff --git a/examples/11_input_controls.lua b/examples/11_input_controls.lua index 43a4159..7269fec 100644 --- a/examples/11_input_controls.lua +++ b/examples/11_input_controls.lua @@ -72,7 +72,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 8, - callback = function() + onEvent = function() counter = counter + 1 counterDisplay.text = "Counter: " .. counter end @@ -90,7 +90,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 8, - callback = function() + onEvent = function() counter = counter - 1 counterDisplay.text = "Counter: " .. counter end @@ -108,7 +108,7 @@ function Lv.load() textColor = Color.new(1, 1, 1, 1), textAlign = enums.TextAlign.CENTER, cornerRadius = 8, - callback = function() + onEvent = function() counter = 0 counterDisplay.text = "Counter: " .. counter end diff --git a/examples/12_z_index_layering.lua b/examples/12_z_index_layering.lua index 3c110c1..468bb00 100644 --- a/examples/12_z_index_layering.lua +++ b/examples/12_z_index_layering.lua @@ -166,7 +166,7 @@ function Lv.load() }) -- Add click handler to bring to front - box.callback = function(element) + box.onEvent = function(element) maxZ = maxZ + 1 element.z = maxZ element.text = "Box " .. i .. "\nZ: " .. element.z diff --git a/examples/13_comprehensive_demo.lua b/examples/13_comprehensive_demo.lua index c679716..a68e516 100644 --- a/examples/13_comprehensive_demo.lua +++ b/examples/13_comprehensive_demo.lua @@ -249,7 +249,7 @@ function Lv.load() }) -- Add hover animation - card.callback = function(element) + card.onEvent = function(element) local anim = Animation.new({ duration = 0.2, start = { opacity = 1 }, diff --git a/examples/14_drag_slider.lua b/examples/14_drag_slider.lua index a228521..2c15720 100644 --- a/examples/14_drag_slider.lua +++ b/examples/14_drag_slider.lua @@ -99,7 +99,7 @@ local function createSlider(x, y, width, label, min, max, initialValue, onValueC }) -- Make the background track interactive - sliderBg.callback = function(element, event) + sliderBg.onEvent = function(element, event) if event.type == "press" or event.type == "drag" then -- Get element bounds local bg_x = element.x diff --git a/modules/Element.lua b/modules/Element.lua index ce0055a..f515fec 100644 --- a/modules/Element.lua +++ b/modules/Element.lua @@ -114,7 +114,7 @@ Public API methods to access internal state: ---@field autoScaleText boolean -- Whether text should auto-scale with window size (default: true) ---@field transform TransformProps -- Transform properties for animations and styling ---@field transition TransitionProps -- Transition settings for animations ----@field callback fun(element:Element, event:InputEvent)? -- Callback function for interaction events +---@field onEvent fun(element:Element, event:InputEvent)? -- Callback function for interaction events ---@field units table -- Original unit specifications for responsive behavior ---@field _pressed table -- Track pressed state per mouse button ---@field _lastClickTime number? -- Timestamp of last click for double-click detection @@ -189,7 +189,7 @@ Element.__index = Element function Element.new(props) local self = setmetatable({}, Element) self.children = {} - self.callback = props.callback + self.onEvent = props.onEvent -- Auto-generate ID in immediate mode if not provided if Gui._immediateMode and (not props.id or props.id == "") then @@ -2503,7 +2503,7 @@ function Element:destroy() self.animation = nil -- Clear callback to prevent closure leaks - self.callback = nil + self.onEvent = nil end --- Draw element and its children @@ -2911,8 +2911,8 @@ function Element:draw(backdropCanvas) end end - -- Draw visual feedback when element is pressed (if it has a callback and highlight is not disabled) - if self.callback and not self.disableHighlight then + -- Draw visual feedback when element is pressed (if it has an onEvent handler and highlight is not disabled) + if self.onEvent and not self.disableHighlight then -- Check if any button is pressed local anyPressed = false for _, pressed in pairs(self._pressed) do @@ -3173,7 +3173,7 @@ function Element:update(dt) end end - if self.callback or self.themeComponent or self.editable then + if self.onEvent or self.themeComponent or self.editable then -- Clickable area is the border box (x, y already includes padding) -- BORDER-BOX MODEL: Use stored border-box dimensions for hit detection local bx = self.x @@ -3269,7 +3269,7 @@ function Element:update(dt) self._themeState = newThemeState end - -- Only process button events if callback exists, element is not disabled, + -- Only process button events if onEvent handler exists, element is not disabled, -- and this is the topmost element at the mouse position (z-index ordering) -- Exception: Allow drag continuation even if occluded (once drag starts, it continues) local isDragging = false @@ -3280,7 +3280,7 @@ function Element:update(dt) end end - local canProcessEvents = (self.callback or self.editable) and not self.disabled and (isActiveElement or isDragging) + local canProcessEvents = (self.onEvent or self.editable) and not self.disabled and (isActiveElement or isDragging) if canProcessEvents then -- Check all three mouse buttons @@ -3299,7 +3299,7 @@ function Element:update(dt) else -- Just pressed - fire press event and record drag start position local modifiers = getModifiers() - if self.callback then + if self.onEvent then local pressEvent = InputEvent.new({ type = "press", button = button, @@ -3308,7 +3308,7 @@ function Element:update(dt) modifiers = modifiers, clickCount = 1, }) - self.callback(self, pressEvent) + self.onEvent(self, pressEvent) end self._pressed[button] = true @@ -3331,7 +3331,7 @@ function Element:update(dt) if lastX ~= mx or lastY ~= my then -- Mouse has moved - fire drag event only if still hovering - if self.callback and isHovering then + if self.onEvent and isHovering then local modifiers = getModifiers() local dx = mx - self._dragStartX[button] local dy = my - self._dragStartY[button] @@ -3346,7 +3346,7 @@ function Element:update(dt) modifiers = modifiers, clickCount = 1, }) - self.callback(self, dragEvent) + self.onEvent(self, dragEvent) end -- Handle text selection drag for editable elements @@ -3386,7 +3386,7 @@ function Element:update(dt) eventType = "middleclick" end - if self.callback then + if self.onEvent then local clickEvent = InputEvent.new({ type = eventType, button = button, @@ -3396,7 +3396,7 @@ function Element:update(dt) clickCount = clickCount, }) - self.callback(self, clickEvent) + self.onEvent(self, clickEvent) end self._pressed[button] = false @@ -3429,7 +3429,7 @@ function Element:update(dt) end -- Fire release event - if self.callback then + if self.onEvent then local releaseEvent = InputEvent.new({ type = "release", button = button, @@ -3438,7 +3438,7 @@ function Element:update(dt) modifiers = modifiers, clickCount = clickCount, }) - self.callback(self, releaseEvent) + self.onEvent(self, releaseEvent) end end else @@ -3450,10 +3450,10 @@ function Element:update(dt) end end end - end -- end if self.callback + end -- end if self.onEvent -- Handle touch events (maintain backward compatibility) - if self.callback then + if self.onEvent then local touches = love.touch.getTouches() for _, id in ipairs(touches) do local tx, ty = love.touch.getPosition(id) @@ -3469,7 +3469,7 @@ function Element:update(dt) modifiers = getModifiers(), clickCount = 1, }) - self.callback(self, touchEvent) + self.onEvent(self, touchEvent) self._touchPressed[id] = false end end diff --git a/modules/GuiState.lua b/modules/GuiState.lua index b2d04d7..9703df0 100644 --- a/modules/GuiState.lua +++ b/modules/GuiState.lua @@ -131,8 +131,8 @@ function GuiState.getTopElementAt(x, y) local function findInteractiveAncestor(elem) local current = elem while current do - -- An element is interactive if it has a callback, themeComponent, or is editable - if current.callback or current.themeComponent or current.editable then + -- An element is interactive if it has an onEvent handler, themeComponent, or is editable + if current.onEvent or current.themeComponent or current.editable then return current end current = current.parent diff --git a/modules/StateManager.lua b/modules/StateManager.lua index 531895c..ec908cb 100644 --- a/modules/StateManager.lua +++ b/modules/StateManager.lua @@ -60,7 +60,7 @@ local function hashProps(props, visited, depth) -- Properties to skip (they cause issues or aren't relevant for ID generation) local skipKeys = { - callback = true, + onEvent = true, parent = true, children = true, onFocus = true, diff --git a/modules/utils.lua b/modules/utils.lua index 1e97751..3c2bf09 100644 --- a/modules/utils.lua +++ b/modules/utils.lua @@ -34,7 +34,7 @@ ---@field flexWrap FlexWrap? -- Whether children wrap to multiple lines: "nowrap"|"wrap"|"wrap-reverse" (default: NOWRAP) ---@field justifySelf JustifySelf? -- Alignment of the item itself along main axis (default: AUTO) ---@field alignSelf AlignSelf? -- Alignment of the item itself along cross axis (default: AUTO) ----@field callback fun(element:Element, event:InputEvent)? -- Callback function for interaction events +---@field onEvent fun(element:Element, event:InputEvent)? -- Callback function for interaction events ---@field onFocus fun(element:Element, event:InputEvent)? -- Callback when element receives focus ---@field onBlur fun(element:Element, event:InputEvent)? -- Callback when element loses focus ---@field onTextInput fun(element:Element, text:string)? -- Callback when text is input diff --git a/testing/__tests__/16_event_system_tests.lua b/testing/__tests__/16_event_system_tests.lua index eae2c40..bbcda3d 100644 --- a/testing/__tests__/16_event_system_tests.lua +++ b/testing/__tests__/16_event_system_tests.lua @@ -49,7 +49,7 @@ function TestEventSystem:test_event_object_has_required_fields() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) eventReceived = event end, }) @@ -82,7 +82,7 @@ function TestEventSystem:test_left_click_generates_click_event() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) table.insert(eventsReceived, { type = event.type, button = event.button }) end, }) @@ -118,7 +118,7 @@ function TestEventSystem:test_right_click_generates_rightclick_event() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) table.insert(eventsReceived, { type = event.type, button = event.button }) end, }) @@ -151,7 +151,7 @@ function TestEventSystem:test_middle_click_generates_middleclick_event() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) table.insert(eventsReceived, { type = event.type, button = event.button }) end, }) @@ -184,7 +184,7 @@ function TestEventSystem:test_modifier_keys_are_detected() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then eventReceived = event end @@ -213,7 +213,7 @@ function TestEventSystem:test_double_click_increments_click_count() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then table.insert(clickEvents, event.clickCount) end @@ -248,7 +248,7 @@ function TestEventSystem:test_press_and_release_events_are_fired() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) table.insert(eventsReceived, event.type) end, }) @@ -288,7 +288,7 @@ function TestEventSystem:test_event_contains_mouse_position() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then eventReceived = event end @@ -318,7 +318,7 @@ function TestEventSystem:test_no_callback_when_clicking_outside_element() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) callbackCalled = true end, }) @@ -343,7 +343,7 @@ function TestEventSystem:test_multiple_modifiers_detected() y = 100, width = 200, height = 100, - callback = function(element, event) + onEvent = function(element, event) if event.type == "click" then eventReceived = event end diff --git a/testing/__tests__/29_drag_event_tests.lua b/testing/__tests__/29_drag_event_tests.lua index 4fecdee..8573ee8 100644 --- a/testing/__tests__/29_drag_event_tests.lua +++ b/testing/__tests__/29_drag_event_tests.lua @@ -32,7 +32,7 @@ function TestDragEvent:test_drag_event_fired_on_mouse_movement() y = 100, width = 200, height = 100, - callback = function(el, event) + onEvent = function(el, event) if event.type == "drag" then dragEventReceived = true dragEvent = event @@ -62,7 +62,7 @@ function TestDragEvent:test_drag_event_contains_delta_values() y = 100, width = 200, height = 100, - callback = function(el, event) + onEvent = function(el, event) if event.type == "drag" then dragEvent = event end @@ -94,7 +94,7 @@ function TestDragEvent:test_drag_event_updates_delta_continuously() y = 100, width = 200, height = 100, - callback = function(el, event) + onEvent = function(el, event) if event.type == "drag" then table.insert(dragEvents, { dx = event.dx, dy = event.dy }) end @@ -130,7 +130,7 @@ function TestDragEvent:test_no_drag_event_when_mouse_stationary() y = 100, width = 200, height = 100, - callback = function(el, event) + onEvent = function(el, event) if event.type == "drag" then dragEventCount = dragEventCount + 1 end @@ -158,7 +158,7 @@ function TestDragEvent:test_drag_tracking_cleaned_up_on_release() y = 100, width = 200, height = 100, - callback = function(el, event) + onEvent = function(el, event) if event.type == "drag" then table.insert(dragEvents, { dx = event.dx, dy = event.dy }) end @@ -199,7 +199,7 @@ function TestDragEvent:test_drag_works_with_different_buttons() y = 100, width = 200, height = 100, - callback = function(el, event) + onEvent = function(el, event) if event.type == "drag" then table.insert(dragEvents, { button = event.button, dx = event.dx }) end @@ -232,7 +232,7 @@ function TestDragEvent:test_drag_event_contains_mouse_position() y = 100, width = 200, height = 100, - callback = function(el, event) + onEvent = function(el, event) if event.type == "drag" then dragEvent = event end @@ -260,7 +260,7 @@ function TestDragEvent:test_no_drag_when_mouse_leaves_element() y = 100, width = 200, height = 100, - callback = function(el, event) + onEvent = function(el, event) if event.type == "drag" then dragEventCount = dragEventCount + 1 end