Add offset to grid components to center nodes

This commit is contained in:
Insality 2020-09-28 01:35:44 +03:00
parent a6963f1055
commit caeb3bbf2f
3 changed files with 62 additions and 73 deletions

View File

@ -131,13 +131,10 @@ function DynamicGrid:add(node, index, is_shift_left)
local start_index = is_shift_left and self.first_index or self.last_index local start_index = is_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]
print("move", i + delta, i)
end end
end end
-- TODO: we must choose anchor node to add this node (next or previous)
self:_add_node(node, index, index - delta) self:_add_node(node, index, index - delta)
print("Add", index, "From", index - delta)
-- After shifting we should recalc node poses -- After shifting we should recalc node poses
if is_shift then if is_shift then
@ -145,11 +142,11 @@ function DynamicGrid:add(node, index, is_shift_left)
local target_index = is_shift_left and self.first_index or self.last_index local target_index = is_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]
print("Recalc", i, i - delta)
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()
@ -310,11 +307,13 @@ end
function DynamicGrid:_update_pos(is_instant) function DynamicGrid:_update_pos(is_instant)
local offset = self:get_zero_offset()
for index, node in pairs(self.nodes) do for index, node in pairs(self.nodes) do
if is_instant then if is_instant then
gui.set_position(node.node, node.pos) gui.set_position(node.node, node.pos + offset)
else else
self._set_position_function(node.node, node.pos) self._set_position_function(node.node, node.pos + offset)
end end
end end
@ -363,7 +362,7 @@ function DynamicGrid:_add_node(node, index, origin_index)
-- Add new item instantly in new pos -- Add new item instantly in new pos
gui.set_parent(node, self.parent) gui.set_parent(node, self.parent)
gui.set_position(node, self.nodes[index].pos) gui.set_position(node, self.nodes[index].pos + self:get_zero_offset())
end end

View File

@ -41,8 +41,8 @@ function StaticGrid:init(parent, element, in_row)
self.offset = vmath.vector3(0) self.offset = vmath.vector3(0)
local pivot = helper.get_pivot_offset(gui.get_pivot(self.parent)) self.pivot = helper.get_pivot_offset(gui.get_pivot(self.parent))
self.anchor = vmath.vector3(0.5 + pivot.x, 0.5 - pivot.y, 0) self.anchor = vmath.vector3(0.5 + self.pivot.x, 0.5 - self.pivot.y, 0)
self.in_row = in_row or 1 self.in_row = in_row or 1
@ -51,7 +51,6 @@ function StaticGrid:init(parent, element, in_row)
self.node_pivot = const.PIVOTS[gui.get_pivot(self._prefab)] self.node_pivot = const.PIVOTS[gui.get_pivot(self._prefab)]
self.border = vmath.vector4(0) -- Current grid content size self.border = vmath.vector4(0) -- Current grid content size
self.border_offset = vmath.vector3(0) -- Content offset for match the grid anchoring
self.on_add_item = Event() self.on_add_item = Event()
self.on_remove_item = Event() self.on_remove_item = Event()
@ -72,8 +71,8 @@ function StaticGrid:get_pos(index)
local row = math.ceil(index / self.in_row) - 1 local row = math.ceil(index / self.in_row) - 1
local col = (index - row * self.in_row) - 1 local col = (index - row * self.in_row) - 1
_temp_pos.x = col * (self.node_size.x + self.offset.x) - self.border_offset.x _temp_pos.x = col * (self.node_size.x + self.offset.x)
_temp_pos.y = -row * (self.node_size.y + self.offset.y) - self.border_offset.y _temp_pos.y = -row * (self.node_size.y + self.offset.y)
_temp_pos.z = 0 _temp_pos.z = 0
return _temp_pos return _temp_pos
@ -85,8 +84,8 @@ end
-- @tparam vector3 pos The node position in the grid -- @tparam vector3 pos The node position in the grid
-- @treturn number The node index -- @treturn number The node index
function StaticGrid:get_index(pos) function StaticGrid:get_index(pos)
local col = (pos.x + self.border_offset.x) / (self.node_size.x + self.offset.x) + 1 local col = pos.x / (self.node_size.x + self.offset.x) + 1
local row = -(pos.y + self.border_offset.y) / (self.node_size.y + self.offset.y) local row = -pos.y / (self.node_size.y + self.offset.y)
col = helper.round(col) col = helper.round(col)
row = helper.round(row) row = helper.round(row)
@ -112,7 +111,7 @@ end
function StaticGrid:on_layout_change() function StaticGrid:on_layout_change()
self:_update_pos(true) self:_update(true)
end end
@ -121,7 +120,7 @@ end
-- @tparam vector3 offset Offset -- @tparam vector3 offset Offset
function StaticGrid:set_offset(offset) function StaticGrid:set_offset(offset)
self.offset = offset self.offset = offset
self:_update_pos() self:_update()
end end
@ -130,7 +129,7 @@ end
-- @tparam vector3 anchor Anchor -- @tparam vector3 anchor Anchor
function StaticGrid:set_anchor(anchor) function StaticGrid:set_anchor(anchor)
self.anchor = anchor self.anchor = anchor
self:_update_pos() self:_update()
end end
@ -156,12 +155,7 @@ function StaticGrid:add(item, index)
-- Add new item instantly in new pos -- Add new item instantly in new pos
gui.set_position(item, pos) gui.set_position(item, pos)
for i, _ in pairs(self.nodes) do self:_update()
self:_update_border_offset(self:get_pos(i))
end
self:_update_pos()
self:_update_indexes()
self.on_add_item:trigger(self:get_context(), item, index) self.on_add_item:trigger(self:get_context(), item, index)
self.on_change_items:trigger(self:get_context(), index) self.on_change_items:trigger(self:get_context(), index)
@ -185,13 +179,8 @@ function StaticGrid:remove(index, is_shift_nodes)
-- Recalculate borders -- Recalculate borders
self.border = vmath.vector4(0) self.border = vmath.vector4(0)
self:_update_border_offset(self:get_pos(1))
for i, _ in pairs(self.nodes) do
self:_update_border_offset(self:get_pos(i))
end
self:_update_pos() self:_update()
self:_update_indexes()
self.on_add_item:trigger(self:get_context(), index) self.on_add_item:trigger(self:get_context(), index)
self.on_change_items:trigger(self:get_context(), index) self.on_change_items:trigger(self:get_context(), index)
@ -210,21 +199,6 @@ function StaticGrid:get_size(border)
end end
--- Return grid size for amount of nodes in this grid
-- @function static_grid:get_size_for_elements_count
-- @tparam number count The grid content node amount
-- @treturn vector3 The grid content size
function StaticGrid:get_size_for_elements_count(count)
local border = vmath.vector4(0)
for i = 1, count do
local pos = self:get_pos(i)
self:_update_border(pos, border)
end
return self:get_size(border)
end
--- Return array of all node positions --- Return array of all node positions
-- @function static_grid:get_all_pos -- @function static_grid:get_all_pos
-- @treturn vector3[] All grid node positions -- @treturn vector3[] All grid node positions
@ -256,10 +230,18 @@ function StaticGrid:clear()
self.border.w = 0 self.border.w = 0
self.border.z = 0 self.border.z = 0
self:_update_border_offset(self:get_pos(1))
self.nodes = {} self.nodes = {}
self:_update_indexes() self:_update()
end
function StaticGrid:get_zero_offset()
-- zero offset: center pos - border size * anchor
return vmath.vector3(
-((self.border.x + self.border.z)/2 + (self.border.z - self.border.x) * self.pivot.x),
-((self.border.y + self.border.w)/2 + (self.border.y - self.border.w) * self.pivot.y),
0
)
end end
@ -271,6 +253,13 @@ function StaticGrid:get_nodes()
end end
function StaticGrid:_update(is_instant)
self:_update_indexes()
self:_update_borders()
self:_update_pos(is_instant)
end
function StaticGrid:_update_indexes() function StaticGrid:_update_indexes()
self.first_index = nil self.first_index = nil
self.last_index = nil self.last_index = nil
@ -284,40 +273,44 @@ function StaticGrid:_update_indexes()
end end
function StaticGrid:_update_border(pos, border) function StaticGrid:_update_borders()
local size = self.node_size if not self.first_index then
local pivot = self.node_pivot self.border = vmath.vector4(0)
return
local left = pos.x - size.x/2 - (size.x * pivot.x) + self.border_offset.x
local right = pos.x + size.x/2 - (size.x * pivot.x) + self.border_offset.x
local top = pos.y + size.y/2 - (size.y * pivot.y) + self.border_offset.y
local bottom = pos.y - size.y/2 - (size.y * pivot.y) + self.border_offset.y
border.x = math.min(border.x, left)
border.y = math.max(border.y, top)
border.z = math.max(border.z, right)
border.w = math.min(border.w, bottom)
end end
self.border = vmath.vector4(math.huge, -math.huge, -math.huge, math.huge)
function StaticGrid:_update_border_offset(pos) local size = self.node_size
local border = self.border local pivot = self.node_pivot
self:_update_border(pos, border) for index, node in pairs(self.nodes) do
local pos = self:get_pos(index)
self.border_offset = vmath.vector3( local left = pos.x - size.x/2 - (size.x * pivot.x)
(border.x + (border.z - border.x) * self.anchor.x), local right = pos.x + size.x/2 - (size.x * pivot.x)
(border.y + (border.w - border.y) * self.anchor.y), local top = pos.y + size.y/2 - (size.y * pivot.y)
0 local bottom = pos.y - size.y/2 - (size.y * pivot.y)
)
self.border.x = math.min(self.border.x, left)
self.border.y = math.max(self.border.y, top)
self.border.z = math.max(self.border.z, right)
self.border.w = math.min(self.border.w, bottom)
end
end end
function StaticGrid:_update_pos(is_instant) function StaticGrid:_update_pos(is_instant)
local zero_offset = self:get_zero_offset()
for i, node in pairs(self.nodes) do for i, node in pairs(self.nodes) do
local pos = self:get_pos(i)
pos.x = pos.x + zero_offset.x
pos.y = pos.y + zero_offset.y
if is_instant then if is_instant then
gui.set_position(node, self:get_pos(i)) gui.set_position(node, pos)
else else
self._set_position_function(node, self:get_pos(i)) self._set_position_function(node, pos)
end end
end end

View File

@ -85,7 +85,6 @@ local function remove_dynamic_node(self, button)
if self.dynamic_node_buttons[i] == button then if self.dynamic_node_buttons[i] == button then
table.remove(self.dynamic_node_buttons, i) table.remove(self.dynamic_node_buttons, i)
self.grid_dynamic_scroll:set_size(self.dynamic_grid:get_size()) self.grid_dynamic_scroll:set_size(self.dynamic_grid:get_size())
self.grid_dynamic_scroll:set_scroll_offset(self.dynamic_grid:get_zero_offset())
break break
end end
end end
@ -103,7 +102,6 @@ local function add_node_dynamic(self, index, is_shift_left)
end) end)
button:set_click_zone(self.grid_dynamic_scroll.view_node) button:set_click_zone(self.grid_dynamic_scroll.view_node)
self.grid_dynamic_scroll:set_size(self.dynamic_grid:get_size()) self.grid_dynamic_scroll:set_size(self.dynamic_grid:get_size())
self.grid_dynamic_scroll:set_scroll_offset(self.dynamic_grid:get_zero_offset())
table.insert(self.dynamic_node_buttons, button) table.insert(self.dynamic_node_buttons, button)
end end
@ -114,7 +112,6 @@ local function add_node_dynamic_hor(self, index)
gui.set_size(node, vmath.vector3(80 + math.random(0, 80), 80, 0)) gui.set_size(node, vmath.vector3(80 + math.random(0, 80), 80, 0))
self.dynamic_hor_grid:add(node, index) self.dynamic_hor_grid:add(node, index)
self.grid_dynamic_hor_scroll:set_size(self.dynamic_hor_grid:get_size()) self.grid_dynamic_hor_scroll:set_size(self.dynamic_hor_grid:get_size())
self.grid_dynamic_hor_scroll:set_scroll_offset(self.dynamic_hor_grid:get_zero_offset())
end end