--[[-- WidgetContainer is a container for another Widget. Base class for all the widget containers. It handles event propagation and paiting (with different alignments) for its children. ]] local Geom = require("ui/geometry") local Widget = require("ui/widget/widget") if require("device"):isAndroid() then require("jit").off(true, true) end local WidgetContainer = Widget:new() function WidgetContainer:init() if self.dimen then if self.initDimen then self:initDimen() else if not self.dimen.w then self.dimen.w = self[1]:getSize().w end if not self.dimen.h then self.dimen.h = self[1]:getSize().h end end end end function WidgetContainer:getSize() if self.dimen then -- fixed size return self.dimen elseif self[1] then -- return size of first child widget return self[1]:getSize() else return Geom:new{ w = 0, h = 0 } end end --[[-- Delete all child widgets ]] function WidgetContainer:clear() while table.remove(self) do end end function WidgetContainer:paintTo(bb, x, y) -- default to pass request to first child widget if self[1] then x = x + (self.dimen.x or 0) y = y + (self.dimen.y or 0) if self.align == "top" then local contentSize = self[1]:getSize() self[1]:paintTo(bb, x + math.floor((self.dimen.w - contentSize.w)/2), y) elseif self.align == "bottom" then local contentSize = self[1]:getSize() self[1]:paintTo(bb, x + math.floor((self.dimen.w - contentSize.w)/2), y + (self.dimen.h - contentSize.h)) elseif self.align == "center" then local contentSize = self[1]:getSize() self[1]:paintTo(bb, x + math.floor((self.dimen.w - contentSize.w)/2), y + math.floor((self.dimen.h - contentSize.h)/2)) else return self[1]:paintTo(bb, x, y) end end end function WidgetContainer:propagateEvent(event) -- propagate to children for _, widget in ipairs(self) do if widget:handleEvent(event) then -- stop propagating when an event handler returns true return true end end return false end --[[-- WidgetContainer will pass event to its children by calling their handleEvent methods. If no child responded to the event (by returning true), it will call its own handleEvent method. @tparam ui.event.Event event @treturn bool true if event is consumed, othewise false. A consumed event will not be sent to other widgets. ]] function WidgetContainer:handleEvent(event) if not self:propagateEvent(event) then -- call our own standard event handler return Widget.handleEvent(self, event) else return true end end function WidgetContainer:free() for _, widget in ipairs(self) do if widget.free then widget:free() end end end return WidgetContainer