Add shift policy to grids

This commit is contained in:
Insality 2020-11-08 23:20:16 +03:00
parent 560c6cb95f
commit 74efdbfe71
4 changed files with 57 additions and 24 deletions

View File

@ -159,13 +159,21 @@ end
-- @tparam StaticGrid self -- @tparam StaticGrid self
-- @tparam node item Gui node -- @tparam node item Gui node
-- @tparam[opt] number index The item position. By default add as last item -- @tparam[opt] number index The item position. By default add as last item
function StaticGrid.add(self, item, index) -- @tparam[opt=SHIFT.RIGHT] number shift_policy How shift nodes, if required. See const.SHIFT
function StaticGrid.add(self, item, index, shift_policy)
shift_policy = shift_policy or const.SHIFT.RIGHT
index = index or ((self.last_index or 0) + 1) index = index or ((self.last_index or 0) + 1)
if self.nodes[index] then if self.nodes[index] then
-- Move nodes to right if shift_policy == const.SHIFT.RIGHT then
for i = self.last_index, index, -1 do for i = self.last_index, index, -1 do
self.nodes[i + 1] = self.nodes[i] self.nodes[i + 1] = self.nodes[i]
end
end
if shift_policy == const.SHIFT.LEFT then
for i = self.first_index, index do
self.nodes[i - 1] = self.nodes[i]
end
end end
end end
@ -189,19 +197,25 @@ end
--- Remove the item from the grid. Note that gui node will be not deleted --- Remove the item from the grid. Note that gui node will be not deleted
-- @tparam StaticGrid self -- @tparam StaticGrid self
-- @tparam number index The grid node index to remove -- @tparam number index The grid node index to remove
-- @tparam bool is_shift_nodes If true, will shift nodes left after index -- @tparam[opt=SHIFT.RIGHT] number shift_policy How shift nodes, if required. See const.SHIFT
-- @treturn Node The deleted gui node from grid -- @treturn Node The deleted gui node from grid
function StaticGrid.remove(self, index, is_shift_nodes) function StaticGrid.remove(self, index, shift_policy)
shift_policy = shift_policy or const.SHIFT.RIGHT
assert(self.nodes[index], "No grid item at given index " .. index) assert(self.nodes[index], "No grid item at given index " .. index)
local remove_node = self.nodes[index] local remove_node = self.nodes[index]
self.nodes[index] = nil self.nodes[index] = nil
if is_shift_nodes then if shift_policy == const.SHIFT.RIGHT then
for i = index, self.last_index do for i = index, self.last_index do
self.nodes[i] = self.nodes[i + 1] self.nodes[i] = self.nodes[i + 1]
end end
end end
if shift_policy == const.SHIFT.LEFT then
for i = index, self.first_index, -1 do
self.nodes[i] = self.nodes[i - 1]
end
end
self:_update() self:_update()

View File

@ -89,6 +89,13 @@ M.OS = {
} }
M.SHIFT = {
NO_SHIFT = 0,
LEFT = -1,
RIGHT = 1,
}
M.SIDE = { M.SIDE = {
X = "x", X = "x",
Y = "y" Y = "y"

View File

@ -136,18 +136,19 @@ end
-- @tparam DynamicGrid self -- @tparam DynamicGrid self
-- @tparam node node Gui node -- @tparam node node Gui node
-- @tparam[opt] number index The node position. By default add as last node -- @tparam[opt] number index The node position. By default add as last node
-- @tparam[opt=false] bool is_shift_left If true, shift all nodes to the left, otherwise shift nodes to the right -- @tparam[opt=SHIFT.RIGHT] number shift_policy How shift nodes, if required. See const.SHIFT
function DynamicGrid.add(self, node, index, is_shift_left) function DynamicGrid.add(self, node, index, shift_policy)
local delta = is_shift_left and -1 or 1 shift_policy = shift_policy or const.SHIFT.RIGHT
local delta = shift_policy -- -1 or 1 or 0
-- By default add node at end -- By default add node at end
index = index or ((self.last_index or 0) + 1) index = index or ((self.last_index or 0) + 1)
-- If node exist at index place, shifting them -- If node exist at index place, shifting them
local is_shift = self.nodes[index] local is_shift = self.nodes[index] and shift_policy ~= const.SHIFT.NO_SHIFT
if is_shift then if is_shift then
-- We need to iterate from index to start or end grid, depends of shift side -- We need to iterate from index to start or end grid, depends of shift side
local start_index = is_shift_left and self.first_index or self.last_index local start_index = shift_policy == const.SHIFT.LEFT and self.first_index or self.last_index
for i = start_index, index, -delta do for i = start_index, index, -delta do
self.nodes[i + delta] = self.nodes[i] self.nodes[i + delta] = self.nodes[i]
end end
@ -158,14 +159,13 @@ function DynamicGrid.add(self, node, index, is_shift_left)
-- After shifting we should recalc node poses -- After shifting we should recalc node poses
if is_shift then if is_shift then
-- We need to iterate from placed node to start or end grid, depends of shift side -- We need to iterate from placed node to start or end grid, depends of shift side
local target_index = is_shift_left and self.first_index or self.last_index local target_index = shift_policy == const.SHIFT.LEFT and self.first_index or self.last_index
for i = index + delta, target_index + delta, delta do for i = index + delta, target_index + delta, delta do
local move_node = self.nodes[i] local move_node = self.nodes[i]
move_node.pos = self:get_pos(i, move_node.node, i - delta) move_node.pos = self:get_pos(i, move_node.node, i - delta)
end end
end end
-- Sync grid data -- Sync grid data
self:_update() self:_update()
@ -178,9 +178,11 @@ end
-- @tparam DynamicGrid self -- @tparam DynamicGrid self
-- @tparam number index The grid node index to remove -- @tparam number index The grid node index to remove
-- @tparam[opt=false] bool is_shift_left If true, shift all nodes to the left, otherwise shift nodes to the right -- @tparam[opt=false] bool is_shift_left If true, shift all nodes to the left, otherwise shift nodes to the right
-- @tparam[opt=SHIFT.RIGHT] number shift_policy How shift nodes, if required. See const.SHIFT
-- @treturn Node The deleted gui node from grid -- @treturn Node The deleted gui node from grid
function DynamicGrid.remove(self, index, is_shift_left) function DynamicGrid.remove(self, index, shift_policy)
local delta = is_shift_left and -1 or 1 shift_policy = shift_policy or const.SHIFT.RIGHT
local delta = shift_policy -- -1 or 1 or 0
assert(self.nodes[index], "No grid item at given index " .. index) assert(self.nodes[index], "No grid item at given index " .. index)
@ -189,11 +191,13 @@ function DynamicGrid.remove(self, index, is_shift_left)
self.nodes[index] = nil self.nodes[index] = nil
-- After delete node, we should shift nodes and recalc their poses, depends from is_shift_left -- After delete node, we should shift nodes and recalc their poses, depends from is_shift_left
local target_index = is_shift_left and self.first_index or self.last_index if shift_policy ~= const.SHIFT.NO_SHIFT then
for i = index, target_index, delta do local target_index = shift_policy == const.SHIFT.LEFT and self.first_index or self.last_index
self.nodes[i] = self.nodes[i + delta] for i = index, target_index, delta do
if self.nodes[i] then self.nodes[i] = self.nodes[i + delta]
self.nodes[i].pos = self:get_pos(i, self.nodes[i].node, i - delta) if self.nodes[i] then
self.nodes[i].pos = self:get_pos(i, self.nodes[i].node, i - delta)
end
end end
end end
@ -407,7 +411,6 @@ function DynamicGrid:get_offset()
local offset = vmath.vector3( local offset = vmath.vector3(
(borders.z + borders.x)/2 + size.x * self.pivot.x, (borders.z + borders.x)/2 + size.x * self.pivot.x,
(borders.y + borders.w)/2 + size.y * self.pivot.y, (borders.y + borders.w)/2 + size.y * self.pivot.y,
0,
0) 0)
return offset return offset

View File

@ -1,6 +1,7 @@
--- Manage data for huge dataset in scroll --- Manage data for huge dataset in scroll
--- It requires basic druid scroll and druid grid components --- It requires basic druid scroll and druid grid components
local const = require("druid.const") local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component") local component = require("druid.component")
local M = component.create("infinity_list", { const.ON_UPDATE }) local M = component.create("infinity_list", { const.ON_UPDATE })
@ -12,6 +13,7 @@ function M:init(data_list, scroll, grid, create_function)
self.druid = self:get_druid() self.druid = self:get_druid()
self.scroll = scroll self.scroll = scroll
self.grid = grid self.grid = grid
self.scroll:bind_grid(grid)
self.data = data_list self.data = data_list
self.top_index = 1 self.top_index = 1
@ -46,20 +48,27 @@ function M:set_data(data_list)
end end
function M:scroll_to_index(index)
self.top_index = helper.clamp(index, 1, #self.data)
self:_refresh()
self.scroll.on_scroll:trigger(self:get_context(), self)
end
function M:_add_at(index) function M:_add_at(index)
if self.nodes[index] then if self.nodes[index] then
self:_remove_at(index) self:_remove_at(index)
end end
local node, instance = self.create_function(self.data[index], index) local node, instance = self.create_function(self.data[index], index)
self.grid:add(node, index) self.grid:add(node, index, const.SHIFT.NO_SHIFT)
self.nodes[index] = node self.nodes[index] = node
self.components[index] = instance self.components[index] = instance
end end
function M:_remove_at(index) function M:_remove_at(index)
self.grid:remove(index) self.grid:remove(index, const.SHIFT.NO_SHIFT)
local node = self.nodes[index] local node = self.nodes[index]
gui.delete_node(node) gui.delete_node(node)