From 3bbb4129c6d86bf38733d067773b1be8706971e4 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 7 Nov 2020 22:15:46 +0300 Subject: [PATCH] Add get_offset for grids, add offset for scroll content --- druid/base/scroll.lua | 21 ++++++++++------ druid/base/static_grid.lua | 44 ++++++++++++++++++++++++--------- druid/extended/dynamic_grid.lua | 38 ++++++++++++++++------------ 3 files changed, 68 insertions(+), 35 deletions(-) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index 7f76bb6..7d6b4d9 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -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 diff --git a/druid/base/static_grid.lua b/druid/base/static_grid.lua index 86f1c13..cbc5dda 100644 --- a/druid/base/static_grid.lua +++ b/druid/base/static_grid.lua @@ -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 diff --git a/druid/extended/dynamic_grid.lua b/druid/extended/dynamic_grid.lua index e2b618f..91b14c3 100644 --- a/druid/extended/dynamic_grid.lua +++ b/druid/extended/dynamic_grid.lua @@ -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