local rectunion = require('lib.gear.rect').union local Widget = { __call = function(cls, args) return cls.new(args) end } Widget.__index = Widget local function raise(widget) local parent = widget.parent -- A parent of a widget is necessarily a Layout while parent ~= nil do local stack = parent.stack -- Move widget at the end of the stack, so it is rendered last. for i,w in ipairs(stack) do if w == widget then table.remove(stack, i) stack[#stack+1] = widget break end end -- Focus widget's container, if any widget = parent parent = widget.parent end end function Widget:grabFocus() local ui = self.ui local focused = ui.focused if focused == self then return end if focused ~= nil then -- Notify leave focused.hovered = false if focused.grabkeyboard then if love.system.getOS() == 'Android' or love.system.getOS() == 'iOS' then love.keyboard.setTextInput(false) end love.keyboard.setKeyRepeat(false) end focused:onLeave() end local wasHovered = self.hovered self.hovered = true if self.grabkeyboard then love.keyboard.setTextInput(true, self.x,self.y,self.w,self.h) love.keyboard.setKeyRepeat(true) end if not wasHovered then -- First time hovered, notify enter self:onEnter() end -- Raise widget ui.focused = self raise(self) end function Widget:isFocused() return self.ui.focused == self end function Widget.recalculateBounds() local widget = self.parent while widget ~= nil do local rx,ry,rw,rh = widget.x,widget.y,-1,-1 for _,w in ipairs(widget) do rx,ry,rw,rh = rectunion(rx,ry,rw,rh, w.x,w.y,w.w,w.h) end widget.x = rx widget.y = ry widget.w = rw widget.h = rh widget = widget.parent end end -- Helper for drawing function Widget:colorForState() if self.active then return self.color.active elseif self:isFocused() then return self.color.hovered else return self.color.normal end end -- Common NOP event handlers function Widget:onHit() end function Widget:onEnter() end function Widget:onLeave() end function Widget:onChange() end -- NOP input event handlers function Widget:onActionInput(action) end function Widget:onPointerInput(x,y, clicked) end -- NOP UI event handlers function Widget:update(dt) end function Widget:draw() end return Widget