Lift common functionality to prop
This commit is contained in:
parent
a96102dc48
commit
3bb7a69577
@ -4,30 +4,6 @@ local Element = require("gfx.element")
|
|||||||
|
|
||||||
local Container = Prop.attach(Element:new(), Children)
|
local Container = Prop.attach(Element:new(), Children)
|
||||||
|
|
||||||
function Container:draw()
|
|
||||||
local dirty = Element.draw(self)
|
|
||||||
if dirty then
|
|
||||||
self:_getWindow().clear()
|
|
||||||
for _,child in self:_iterateChildren() do
|
|
||||||
child:draw()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return dirty
|
|
||||||
end
|
|
||||||
|
|
||||||
function Container:_isDirty()
|
|
||||||
if Element._isDirty(self) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
for _,child in self:_iterateChildren() do
|
|
||||||
if child:_isDirty() then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function Container:_reload()
|
function Container:_reload()
|
||||||
Element._reload(self)
|
Element._reload(self)
|
||||||
|
|
||||||
|
171
gfx/list.lua
171
gfx/list.lua
@ -1,102 +1,44 @@
|
|||||||
local Event = require("gfx.event")
|
local Event = require("gfx.event")
|
||||||
local Element = require("gfx.element")
|
local Element = require("gfx.element")
|
||||||
local List = Element:new{
|
local Prop = require("gfx.prop")
|
||||||
children = {},
|
local Orientation = require("gfx.prop.orientation")
|
||||||
vertical = false
|
local Children = require("gfx.prop.children")
|
||||||
}
|
local List = Prop.attach(Prop.attach(Element:new(), Orientation), Children)
|
||||||
|
|
||||||
local function adjustPositions(elements, vertical, from)
|
function List:adjustPositions(from)
|
||||||
local newDims = 1
|
from = from or 1
|
||||||
local getDim = vertical and function(e) return e:getHeight() end or function(e) return e:getWidth() end
|
local vertical = self:isVertical()
|
||||||
for i=1,from-1 do
|
local newDims = 1
|
||||||
newDims = newDims + getDim(elements[i])
|
local getDim = vertical and function(e) return e:getHeight() end or function(e) return e:getWidth() end
|
||||||
end
|
for _,element in self:_iterateChildren{ to = from } do
|
||||||
|
newDims = newDims + getDim(element)
|
||||||
local setDim = vertical and function(e, dim) e:setY(dim) end or function(e, dim) e:setX(dim) end
|
end
|
||||||
for i=from,#elements do
|
|
||||||
setDim(elements[i], newDims)
|
local setDim = vertical and function(e, dim) e:setY(dim) end or function(e, dim) e:setX(dim) end
|
||||||
newDims = newDims + getDim(elements[i])
|
for _, element in self:_iterateChildren{ from = from } do
|
||||||
end
|
setDim(element, newDims)
|
||||||
|
newDims = newDims + getDim(element)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function List:insertChild(child, atIndex)
|
function List:insertChild(child, atIndex)
|
||||||
local index = math.min(math.max(1, atIndex or #self.children), #self.children)
|
self:_addChild(child, atIndex)
|
||||||
table.insert(self.children, index, child)
|
|
||||||
|
|
||||||
-- Update window references
|
|
||||||
self:_reload()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function List:removeChild(child)
|
function List:removeChild(child)
|
||||||
local index
|
return self:_removeChild(child)
|
||||||
local searchType = type(child)
|
|
||||||
if searchType == "string" then
|
|
||||||
for i,v in ipairs(self.children) do
|
|
||||||
if v:getId() == child then
|
|
||||||
index = i
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false, nil
|
|
||||||
elseif searchType == "table" then
|
|
||||||
for i,v in ipairs(self.children) do
|
|
||||||
if v == child then
|
|
||||||
index = i
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false, nil
|
|
||||||
else
|
|
||||||
index = child
|
|
||||||
end
|
|
||||||
|
|
||||||
if index <= 0 or index > #self.children then
|
|
||||||
return false, nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local removed = table.remove(self.children, index)
|
|
||||||
self:_reload()
|
|
||||||
|
|
||||||
return true, removed
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function List:isVertical()
|
local function maxOrSum(shouldSum, iter, getValue)
|
||||||
return self.vertical
|
|
||||||
end
|
|
||||||
|
|
||||||
function List:isHorizontal()
|
|
||||||
return not self:isVertical()
|
|
||||||
end
|
|
||||||
|
|
||||||
function List:setDirty(fullInvalidate)
|
|
||||||
Element.setDirty(self, fullInvalidate)
|
|
||||||
if fullInvalidate then
|
|
||||||
for _,child in self.children do
|
|
||||||
child:setDirty(fullInvalidate)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function List:draw()
|
|
||||||
local dirty = Element.draw(self)
|
|
||||||
if dirty then
|
|
||||||
self:_getWindow().clear()
|
|
||||||
for _,child in ipairs(self.children) do
|
|
||||||
child:draw()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return dirty
|
|
||||||
end
|
|
||||||
|
|
||||||
local function maxOrSum(shouldSum, values, getValue)
|
|
||||||
if shouldSum then
|
if shouldSum then
|
||||||
local sum = 0
|
local sum = 0
|
||||||
for _,v in ipairs(values) do
|
for _,v in iter() do
|
||||||
sum = sum + getValue(v)
|
sum = sum + getValue(v)
|
||||||
end
|
end
|
||||||
return sum
|
return sum
|
||||||
else
|
else
|
||||||
local max = 0
|
local max = 0
|
||||||
for _,v in ipairs(values) do
|
for _,v in iter() do
|
||||||
max = math.max(max, getValue(v))
|
max = math.max(max, getValue(v))
|
||||||
end
|
end
|
||||||
return max
|
return max
|
||||||
@ -104,68 +46,13 @@ local function maxOrSum(shouldSum, values, getValue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function List:getHeight()
|
function List:getHeight()
|
||||||
return maxOrSum(self:isVertical(), self.children, function(e) return e:getHeight() end)
|
local lSelf = self
|
||||||
|
return maxOrSum(self:isVertical(), function() return lSelf:_iterateChildren() end, function(e) return e:getHeight() end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function List:getWidth()
|
function List:getWidth()
|
||||||
return maxOrSum(self:isHorizontal(), self.children, function(e) return e:getWidth() end)
|
local lSelf = self
|
||||||
end
|
return maxOrSum(self:isHorizontal(), function() return lSelf:_iterateChildren() end, function(e) return e:getWidth() end)
|
||||||
|
|
||||||
function List:findById(id)
|
|
||||||
local find = Element.findById(self, id)
|
|
||||||
if find then
|
|
||||||
return find
|
|
||||||
end
|
|
||||||
|
|
||||||
for _,v in ipairs(self.children) do
|
|
||||||
local result = v:findById(id)
|
|
||||||
if result then
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function List:handleEvent(evt)
|
|
||||||
if Element.handleEvent(self, evt) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
local evtLocalCoords = Event.toElementLocalPosition(evt, self)
|
|
||||||
|
|
||||||
if Event.isClickEvent(evt) then
|
|
||||||
-- If click is not inside list bounds, we can safely ignore it
|
|
||||||
if not Event.containsClick(self, evt) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
for _,child in ipairs(self.children) do
|
|
||||||
if child:handleEvent(evtLocalCoords) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
else
|
|
||||||
for _,child in ipairs(self.children) do
|
|
||||||
if child:handleEvent(evtLocalCoords) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function List:_isDirty()
|
|
||||||
if Element._isDirty(self) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
for _,child in ipairs(self.children) do
|
|
||||||
if child:_isDirty() then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function List:_reload()
|
function List:_reload()
|
||||||
@ -173,13 +60,13 @@ function List:_reload()
|
|||||||
|
|
||||||
-- Reload child windows
|
-- Reload child windows
|
||||||
local win = self:_getWindow()
|
local win = self:_getWindow()
|
||||||
for _,child in ipairs(self.children) do
|
for _,child in self:_iterateChildren() do
|
||||||
if child:_getWindow() ~= win then
|
if child:_getWindow() ~= win then
|
||||||
child:setParent(win)
|
child:setParent(win)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
adjustPositions(self.children, self:isVertical(), 1)
|
self:adjustPositions()
|
||||||
end
|
end
|
||||||
|
|
||||||
return List
|
return List
|
@ -1,4 +1,6 @@
|
|||||||
local Prop = require("gfx.prop")
|
local Prop = require("gfx.prop")
|
||||||
|
local Element = require("gfx.element")
|
||||||
|
local Event = require("gfx.event")
|
||||||
local Children = Prop:new{ defaultState = {} }
|
local Children = Prop:new{ defaultState = {} }
|
||||||
|
|
||||||
function Children:with(elementType)
|
function Children:with(elementType)
|
||||||
@ -69,6 +71,48 @@ function Children:with(elementType)
|
|||||||
return true, result
|
return true, result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function elementType:setDirty(fullInvalidate)
|
||||||
|
Element.setDirty(self, fullInvalidate)
|
||||||
|
if fullInvalidate then
|
||||||
|
for _,child in self:_iterateChildren() do
|
||||||
|
child:setDirty(fullInvalidate)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function elementType:_isDirty()
|
||||||
|
if Element._isDirty(self) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,child in self:_iterateChildren() do
|
||||||
|
if child:_isDirty() then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function elementType:draw()
|
||||||
|
local dirty = Element.draw(self)
|
||||||
|
if dirty then
|
||||||
|
self:_getWindow().clear()
|
||||||
|
for _,child in self:_iterateChildren() do
|
||||||
|
child:draw()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return dirty
|
||||||
|
end
|
||||||
|
|
||||||
|
function elementType:findById(id)
|
||||||
|
local find = Element.findById(self, id)
|
||||||
|
if find then
|
||||||
|
return find
|
||||||
|
end
|
||||||
|
|
||||||
|
return self:findChildById(id)
|
||||||
|
end
|
||||||
|
|
||||||
function elementType:findChildById(id)
|
function elementType:findChildById(id)
|
||||||
for _,child in self:_iterateChildren() do
|
for _,child in self:_iterateChildren() do
|
||||||
local result = child:findById(id)
|
local result = child:findById(id)
|
||||||
@ -79,6 +123,35 @@ function Children:with(elementType)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function elementType:handleEvent(evt)
|
||||||
|
if Element.handleEvent(self, evt) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local evtLocalCoords = Event.toElementLocalPosition(evt, self)
|
||||||
|
|
||||||
|
if Event.isClickEvent(evt) then
|
||||||
|
-- If click is not inside list bounds, we can safely ignore it
|
||||||
|
if not Event.containsClick(self, evt) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,child in self:_iterateChildren() do
|
||||||
|
if child:handleEvent(evtLocalCoords) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
for _,child in self:_iterateChildren() do
|
||||||
|
if child:handleEvent(evtLocalCoords) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return elementType
|
return elementType
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user