Add get_offset for grids, add offset for scroll content

This commit is contained in:
Insality 2020-11-07 22:15:46 +03:00
parent 2ef2a61dfa
commit 3bbb4129c6
3 changed files with 68 additions and 35 deletions

View File

@ -69,14 +69,17 @@ end
--- Update vector with next conditions:
-- Field x have to <= field z
-- Field y have to <= field w
local function get_border_vector(vector)
local function get_border_vector(vector, offset)
if vector.x > vector.z then
vector.x, vector.z = vector.z, vector.x
end
if vector.y > vector.w then
vector.y, vector.w = vector.w, vector.y
end
vector.x = vector.x - offset.x
vector.z = vector.z - offset.x
vector.y = vector.y - offset.y
vector.w = vector.w - offset.y
return vector
end
@ -145,6 +148,7 @@ function Scroll.init(self, view_node, content_node)
self.selected = nil
self.is_animate = false
self._offset = vmath.vector3(0)
self._is_horizontal_scroll = true
self._is_vertical_scroll = true
self._grid_on_change = nil
@ -262,7 +266,10 @@ end
-- @tparam Scroll self
-- @tparam vector3 size The new size for content node
-- @treturn druid.scroll Current scroll instance
function Scroll.set_size(self, size)
function Scroll.set_size(self, size, offset)
if offset then
self._offset = offset
end
gui.set_size(self.content_node, size)
self:_update_size()
@ -372,9 +379,9 @@ function Scroll.bind_grid(self, grid)
self._grid_on_change = grid.on_change_items
self._grid_on_change_callback = self._grid_on_change:subscribe(function()
self:set_size(grid:get_size())
self:set_size(grid:get_size(), grid:get_offset())
end)
self:set_size(grid:get_size())
self:set_size(grid:get_size(), grid:get_offset())
return self
end
@ -598,7 +605,7 @@ function Scroll._update_size(self)
local content_border = helper.get_border(self.content_node)
local content_size = vmath.mul_per_elem(gui.get_size(self.content_node), gui.get_scale(self.content_node))
self.available_pos = get_border_vector(view_border - content_border)
self.available_pos = get_border_vector(view_border - content_border, self._offset)
self.available_size = get_size_vector(self.available_pos)
self.drag.can_x = self.available_size.x > 0 and self._is_horizontal_scroll
@ -627,7 +634,7 @@ function Scroll._update_size(self)
self.drag.can_y = content_size.y > view_size.y
end
self.available_pos_extra = get_border_vector(view_border - content_border_extra)
self.available_pos_extra = get_border_vector(view_border - content_border_extra, self._offset)
self.available_size_extra = get_size_vector(self.available_pos_extra)
end

View File

@ -49,6 +49,19 @@ local component = require("druid.component")
local StaticGrid = component.create("static_grid", { const.ON_LAYOUT_CHANGE })
local function _extend_border(border, pos, size, pivot)
local left = pos.x - size.x/2 - (size.x * pivot.x)
local right = pos.x + size.x/2 - (size.x * pivot.x)
local top = pos.y + size.y/2 - (size.y * pivot.y)
local bottom = pos.y - size.y/2 - (size.y * pivot.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
--- Component init function
-- @tparam StaticGrid self
-- @tparam node parent The gui node parent, where items will be placed
@ -66,6 +79,7 @@ function StaticGrid.init(self, parent, element, in_row)
self._prefab = self:get_node(element)
self.node_size = gui.get_size(self._prefab)
self.node_pivot = const.PIVOTS[gui.get_pivot(self._prefab)]
self.grid_zero_y = self.node_size.y * self.pivot.y -- Y pos at first grid line
self.border = vmath.vector4(0) -- Current grid content size
@ -209,6 +223,14 @@ function StaticGrid.get_size(self)
end
--- Return grid content borders
-- @tparam StaticGrid self
-- @treturn vector3 The grid content borders
function StaticGrid.get_borders(self)
return self.border
end
--- Return array of all node positions
-- @tparam StaticGrid self
-- @treturn vector3[] All grid node positions
@ -262,12 +284,20 @@ function StaticGrid._get_zero_offset(self)
-- 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),
-((self.grid_zero_y + self.border.w)/2 + (self.grid_zero_y - self.border.w) * self.pivot.y),
0
)
end
-- return vector where content borders starts
function StaticGrid:get_offset()
local zero_offset = self:_get_zero_offset()
local borders = self:get_borders()
return vmath.vector3(0, zero_offset.y + borders.y, 0)
end
--- Update grid inner state
-- @tparam StaticGrid self
-- @tparam bool is_instant If true, node position update instantly, otherwise with set_position_function callback
@ -309,17 +339,7 @@ function StaticGrid._update_borders(self)
local size = self.node_size
local pivot = self.node_pivot
for index, node in pairs(self.nodes) do
local pos = self:get_pos(index)
local left = pos.x - size.x/2 - (size.x * pivot.x)
local right = pos.x + size.x/2 - (size.x * pivot.x)
local top = pos.y + size.y/2 - (size.y * pivot.y)
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)
_extend_border(self.border, self:get_pos(index), size, pivot)
end
end

View File

@ -21,7 +21,7 @@
--- Parent gui node
-- @tfield node parent
--- List of all grid nodes
--- List of all grid elements. Contains from node, pos, size, pivot
-- @tfield node[] nodes
--- The first index of node in grid
@ -220,6 +220,14 @@ function DynamicGrid.get_size(self, border)
end
--- Return grid content borders
-- @tparam DynamicGrid self
-- @treturn vector3 The grid content borders
function DynamicGrid.get_borders(self)
return self.border
end
--- Return grid index by node
-- @tparam DynamicGrid self
-- @tparam node node The gui node in the grid
@ -283,7 +291,7 @@ function DynamicGrid._add_node(self, node, index, origin_index)
-- Add new item instantly in new pos
gui.set_parent(node, self.parent)
gui.set_position(node, self.nodes[index].pos + self:_get_zero_offset())
gui.set_position(node, self.nodes[index].pos)
end
@ -348,13 +356,11 @@ end
-- @tparam bool is_instant If true, node position update instantly, otherwise with set_position_function callback
-- @local
function DynamicGrid._update_pos(self, is_instant)
local offset = self:_get_zero_offset()
for index, node in pairs(self.nodes) do
if is_instant then
gui.set_position(node.node, node.pos + offset)
gui.set_position(node.node, node.pos)
else
self._set_position_function(node.node, node.pos + offset)
self._set_position_function(node.node, node.pos)
end
end
@ -386,17 +392,17 @@ function DynamicGrid._get_node_size(self, node)
end
--- Return elements offset for correct posing nodes. Correct posing at
-- parent pivot node (0:0) with adjusting of node sizes and anchoring
-- @tparam DynamicGrid self
-- @treturn vector3 The offset vector
-- @local
function DynamicGrid._get_zero_offset(self)
-- 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),
function DynamicGrid:get_offset()
-- return vector where content borders starts
local size = self:get_size()
local borders = self:get_borders()
local offset = vmath.vector3(
(borders.z + borders.x)/2 + size.x * self.pivot.x,
(borders.y + borders.w)/2 + size.y * self.pivot.y,
0,
0)
return offset
end